Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Pavel Dvorkin, Вы писали:
_NN>Ок более приближённый тест функция верхнего уровня не оптимизируется , скажем это функция обратного вызова.
<skipped>
Что-то я этот код плохо понимаю
1. CallThrowFunction нигде не вызывается и никому не нужна
2. TestErrorCode вызывает CallErrorCodeFunction, но не анализирует результат. Поэтому имеем следующее. Вот цикл
for (int i = 0; i < count; i++)
{
result = TestErrorCode(result, count);
01081030 mov ecx,esi
01081032 call TestErrorCode (01081000h)
01081037 mov esi,eax
01081039 dec edx
0108103A jne wmain+20h (01081030h)
}
Все верно, TestErrorCode вызывется count раз
А теперь смотрим код TestErrorCode
Упс!
--- c:\users\dvorkin\documents\visual studio 2013\projects\consoleapplication8\consoleapplication8.cpp
CallErrorCodeFunction(count);
return result + 1;
01081000 lea eax,[ecx+1]
}
01081003 ret
Так что ты просто время почти пустого цикла померил.
А теперь смотрим второй цикл
for (int i = 0; i < count; i++)
{
result = TestThrow(result, count);
01081060 mov ecx,esi
01081062 call TestErrorCode (01081000h)
01081067 mov esi,eax
01081069 dec edx
0108106A jne wmain+50h (01081060h)
}
Вот тебе и раз. Компилятор почему-то решил, что здесь можно TestErrorCode вызвать вместо TestThrow. Но это не ошибка компилятора — если в TestThrow вставить printf, вызывается, как положено, TestThrow. Видимо, оптимизатор решил, что можно и ту вызвать, все равно. Может быть, потому что ErrorCodeFunction и ThrowFunction совпадают.
А пока что ты еще раз время почти пустого цикла померил. Времена совпадают
Кстати, если убрать __declspec(noinline), то оба времени равны 0, так как компилятор вообще оба цикла выбрасывает вместе со всем содержимым.
Непростая штука это оптимизатор, очень непростая
Ну а если по существу... Конечно, в зависимости от 1) как часто выполняется throw и 2) как соотносится количество команд на проверку кода возврата с количество команд в самой функции — соотношение может варьироваться в широких пределах.
Если сама функция содержит десяток команд, то дополнительные команды проверки кода возврата могут повлиять на скорость работы. Если же функция читает что-то с диска или из сети, то время для проверки кода возврата есть бесконечно малое по сравнению с временем работы функции.
Если throw происходит один раз на 100500 вызовов — его время есть бесконечно малое по сравнению с суммарным временем работы этих 100500 вызовов. Если каждые 5 раз — то может быть и сравнимо.
Так что истина конкретна.
А я всего лишь хотел показать, что собственно throw — try- catch достаточно затратная операция. А дальше — зависит от того, на фоне каких других затрат.