Думаю общие принципы генерации managed кода в тестах схожи с вашим случаем. Думаю что принципы применяются схожим образом для разных типов. Хотя конечно в каждом случае могут быть свои нюансы.
Но управление кодом вряд-ли может быть бесплатным.
Именно поэтому внизу привел результаты тестирования для VS2015:
«Не вдаваясь в детали: самая быстрая сортировка для C++ заняла 153105, а самая быстрая для C# 206552.
То есть разница порядка 30%»
Тоже самое получается. NGen же влияет только на время запуска ассембли\функции, а весь тест находится в теле одной функции, поэтому к моменту ее запуска уже является скомпилированным.
Тогда можно предположить, что использование managed кода даст дополнительные потери производительности в диапазоне 5-40%, и если загрузка CPU лишь 40%, то порядка 40% от этого диапазона, то есть ориентировочные потери будут лишь 2-16%
(если правда 40% загрузка)
Тесты измеряют лишь скорость выполнения «вашего» кода.
Сколько же времени придется на «ваш» код, а сколько на код системы вы должны определить профайлером или же вывести из собственного опыта в реализации или профилировании подобных задач.
Масштабировать результаты возможно, используя соотношение между временем выполнения вашего кода и кода системы. Соотношение нужно знать априорно, из опыта разработки.
Конкретная цифра будет разной в каждой конкретной задаче. Вы должны знать сколько процентов runtime приходится на ваш сервис, например померив этот процент профайлером и далее делать выводы о необходимости оптимизации.
Обновление: дело было в неправильном получении disassembly.
На самом деле и в случае VS2010 оптимизация вполне приличная, но все-таки несколько хуже чем в случае с С++.
Тесты на 2015 студии показали разницу порядка 30% на платформе Core i7-3770
Какой вариант предложили бы вы?
Но управление кодом вряд-ли может быть бесплатным.
По скольку тестов опровергающих данную разницу нет, считаю оправданным ее использование.
И разумеется восьмикратный разброс вполне объясним т.к. зависит от задачи.
items[j] = items[i];
000000a1 mov ebx,dword ptr [ebp-38h]
000000a4 mov esi,dword ptr [ebp-38h]
000000a7 mov eax,dword ptr [esi+edi*4]
000000aa mov dword ptr [ebx+ecx*4],eax
«Не вдаваясь в детали: самая быстрая сортировка для C++ заняла 153105, а самая быстрая для C# 206552.
То есть разница порядка 30%»
(если правда 40% загрузка)
Сколько же времени придется на «ваш» код, а сколько на код системы вы должны определить профайлером или же вывести из собственного опыта в реализации или профилировании подобных задач.
Масштабировать результаты возможно, используя соотношение между временем выполнения вашего кода и кода системы. Соотношение нужно знать априорно, из опыта разработки.
На самом деле и в случае VS2010 оптимизация вполне приличная, но все-таки несколько хуже чем в случае с С++.
Тесты на 2015 студии показали разницу порядка 30% на платформе Core i7-3770
Собрал тесты под VS2015 и запустил.
Не вдаваясь в детали: самая быстрая сортировка для C++ заняла 153105, а самая быстрая для C# 206552.
То есть разница порядка 30%
Кстати, если использовать items.Length, то код по крайней мере для случая VS2010 получается примерно такой-же.
int tmp;
for (int i = 0; i < items.Length; i++)
0000007d xor ebx,ebx
0000007f mov eax,dword ptr [esi+4]
00000082 mov dword ptr [ebp-44h],eax
00000085 test eax,eax
00000087 jle 000000C3
for (int j = i; j < items.Length; j++)
00000089 mov edi,ebx
0000008b cmp dword ptr [ebp-44h],ebx
0000008e jle 000000BD
00000090 mov eax,dword ptr [esi+4]
00000093 mov dword ptr [ebp-48h],eax
{
if (items[i] < items[j])
00000096 mov edx,dword ptr [esi+ebx*4+8]
0000009a mov eax,dword ptr [ebp-48h]
0000009d cmp edi,eax
0000009f jae 000001BE
000000a5 mov ecx,dword ptr [esi+edi*4+8]
000000a9 cmp edx,ecx
000000ab jge 000000B5
000000ad mov dword ptr [esi+edi*4+8],edx
items[i] = tmp;
000000b1 mov dword ptr [esi+ebx*4+8],ecx
for (int j = i; j < items.Length; j++)
000000b5 add edi,1
000000b8 cmp dword ptr [ebp-44h],edi
000000bb jg 00000096
for (int i = 0; i < items.Length; i++)
000000bd inc ebx
000000be cmp dword ptr [ebp-44h],ebx
000000c1 jg 00000089
}
}