JIT-компиляция представляет собой сложный баланс между тем, чтобы не тратить слишком много времени на этап компиляции (таким образом, значительно замедляя недолговечные приложения), и не делать достаточного количества анализа, чтобы сохранить конкурентоспособность приложения в долгосрочной перспективе с опережающим стандартом. сборник.
Интересно, что шаги компиляции NGen не направлены на то, чтобы быть более агрессивными в их оптимизации. Я подозреваю, что это потому, что они просто не хотят иметь ошибки, поведение которых зависит от того, был ли JIT или NGen ответственным за машинный код.
Сам CLR поддерживает оптимизацию хвостового вызова, но компилятор для конкретного языка должен знать, как генерировать соответствующий код операции , и JIT должен быть готов соблюдать его.
F # fsc сгенерирует соответствующие коды операций (хотя для простой рекурсии он может просто преобразовать все это в цикл while
напрямую). C # не делает CSC.
См. в этом блоге для некоторых деталей (вполне возможно, что сейчас устарел, учитывая недавние изменения JIT). Обратите внимание, что CLR изменяется для 4.0 , x86, x64 и ia64 будут уважать его .