На каком уровне компилятор C# или JIT оптимизируют код приложения?

Я хочу знать эту информацию, чтобы уменьшить размер моего кода, чтобы не тратить свое время на оптимизацию вещей, которые будут выполняться компилятором или JIT.

например:

если мы предположим, что компилятор встроил вызов функции get свойства, поэтому мне не нужно сохранять возвращаемое значение в локальной переменной, чтобы избежать вызова функции.

Я хочу порекомендовать хороший справочник, который описывает, что происходит?

4 ответа

Решение

Вы можете взглянуть на эти статьи:

JIT-оптимизации - (Саша Гольдштейн - CodeProject)
Jit Optimization: Inlining I (Дэвид Нотарио)
Jit Optimization: Inlining II (Дэвид Нотарио)

Честно говоря, вы не должны слишком беспокоиться об этом уровне микродетали. Пусть компилятор /JIT'er позаботится об этом за вас, это лучше, чем вы, почти во всех случаях. Не зацикливайтесь на преждевременной оптимизации. Сосредоточьтесь на том, чтобы ваш код работал, а затем позаботьтесь об оптимизации, если (а) он работает недостаточно быстро, (б) у вас проблемы с размером.

Если вы беспокоитесь о производительности, запустите профилировщик. Затем измените код. Скорее всего, за миллион лет вы никогда не угадаете на 100% правильно, куда идет время. Вы могли бы изменить время 0,02% и оставить метод, который вносит 62% бремени. Вы могли бы также сделать это хуже. Без профайлера и доказательств ты слепой.


Вы не можете предполагать, что JIT встроит получатель свойства. Есть много причин, по которым он может или не может сделать это; размер тела метода, виртуальный, значение в зависимости от ссылочного типа, архитектура, присоединенный отладчик и т. д.

"Подъем" по-прежнему имеет место, и все же может достичь экономии, если код вызывается многократно в узком цикле; например:

var count = list.Count;
for(int i = 0 ; i < count ; i++) {...}

(забудь for против foreach Дебаты о вышеизложенном - это ортогональное обсуждение). В вышеизложенном "подъемник" поможет производительности. Но просто запутать - с массивами все наоборот, и эффективнее не поднимать его:

for(int i = 0 ; i < arr.Length ; i++) {...}

JIT распознает это и снимает проверку границ (так как массивы имеют фиксированный размер).

Это похоже на микрооптимизацию, на которую не стоит смотреть. Если я не ошибаюсь, это зависит от архитектуры и версии CLR, какой тип оптимизации применяется.

Если ваш метод вызывается так часто, и вы действительно хотите встроить его, вы можете встроить его самостоятельно за счет спагетти-кода.

Я бы порекомендовал проанализировать ваш алгоритм, чтобы встроенный метод не сохранял величины скорости, в то время как лучший алгоритм может сократить время работы с часов до секунд.

Наиболее мощная оптимизация, выполняемая JIT, обычно встроенная. JIT может даже включать в себя сотни функций (я слышал эту цифру для JikesRVM). Они даже встроят вещи, которые не всегда возможно встроить, и поддержат их позже, если потребуется (динамическая деоптимизация).

Хорошим обзором является http://java.sun.com/products/hotspot/docs/whitepaper/Java_Hotspot_v1.4.1/Java_HSpot_WP_v1.4.1_1002_4.html.

На ваш конкретный вопрос я бы сказал, вероятно, если рассматриваемый вызов функции горячий.

Другие вопросы по тегам