Почему комментирует первые две строки этого цикла for и раскомментирует третий результат при ускорении на 42%?
int count = 0;
for (uint i = 0; i < 1000000000; ++i) {
var isMultipleOf16 = i % 16 == 0;
count += isMultipleOf16 ? 1 : 0;
//count += i % 16 == 0 ? 1 : 0;
}
За временем очень сильно отличается код сборки: 13 против 7 инструкций в цикле. Платформа - это Windows 7 с .NET 4.0 x64. Оптимизация кода включена, и тестовое приложение запускалось за пределами VS2010. [ Обновление: Проект Repro, полезный для проверки настроек проекта.]
Устранение промежуточной булевой является фундаментальной оптимизацией, одной из самых простых в моей эре 1980 года Книга Дракона. Как оптимизация не применялась при создании CIL или JITing машинного кода x64?
Есть ли "действительно компилятор, я бы хотел, чтобы вы оптимизировали этот код, пожалуйста" переключитесь? В то время как я сочувствую настроениям, что преждевременная оптимизация сродни любви любви, я мог видеть разочарование в попытке профилировать сложный алгоритм, который такие проблемы были разбросаны по всей его рутине. Вы будете работать через горячие точки, но не имеете никакого намека на более широкий теплый регион, который может быть значительно улучшен путем ручной настройки того, что мы обычно принимаем как должное из компилятора. Надеюсь, что я что-то пропустил.
Обновление: Разница скорости также возникает для x86, но зависит от порядка, который методы компилируются точно. См. Почему порядок JIT влияет на производительность?
Код сборки (по запросу):
var isMultipleOf16 = i % 16 == 0;
00000037 mov eax,edx
00000039 and eax,0Fh
0000003c xor ecx,ecx
0000003e test eax,eax
00000040 sete cl
count += isMultipleOf16 ? 1 : 0;
00000043 movzx eax,cl
00000046 test eax,eax
00000048 jne 0000000000000050
0000004a xor eax,eax
0000004c jmp 0000000000000055
0000004e xchg ax,ax
00000050 mov eax,1
00000055 lea r8d,[rbx+rax]
count += i % 16 == 0 ? 1 : 0;
00000037 mov eax,ecx
00000039 and eax,0Fh
0000003c je 0000000000000042
0000003e xor eax,eax
00000040 jmp 0000000000000047
00000042 mov eax,1
00000047 lea edx,[rbx+rax]