Разминка при вызове методов в С#

Я только что наткнулся на этот пост, в котором говорится о измерении времени. Я помню (надеюсь, что не ошибаюсь) это нечестная конкуренция, если этот метод никогда не называется раньше. То есть:

// At the beginning of the application
MyClass instance = new MyClass();
instance.MyMethod();
instance.MyMethod();  // Faster than the first call, because now it warmed up.

Есть ли у нас такая теория прогрева в С#? Если да, то почему (что сделает CLR при разогреве)? И все ли одинаково, если этот метод является расширением (статическим)?

Ответ 1

Если при "разогреве" вы ссылаетесь на JIT'ing, тогда да - если метод никогда не вызывается, он еще не был скомпилирован, поэтому в первый раз, когда вы его запустите, он может быть медленнее. Также см. Скомпилирует ли .NET CLR JIT каждый метод каждый раз?

Ответ 2

Это связано с компиляцией точно в срок (JIT). Если вы хотите повысить производительность и избежать этого эффекта, Генератор собственных изображений (Ngen.exe) может вам помочь.

Ответ 3

То, о чем говорят люди, компиляция точно в срок. Код, созданный в .NET, хранится на промежуточном языке, который не зависит от платформы. Когда вы запускаете прикладные части кода CIL, скомпилируются для инструкций на платформе, которые в первый раз занимают немного времени. Затем он кэшируется, поэтому при следующем вызове метода у вас нет этой потери времени.

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

Ответ 4

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

Из Компиляция MSIL для собственного кода:

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