Рассмотрим простую функцию, такую как:
int SimpleFunc (const int X, const int Y)
{
return (X + 3 * Y);
}
int main(int argc, char* argv[])
{
int Test = SimpleFunc(11, 12);
return 0;
}
Это преобразуется в следующий код (MSVC ++ v6, отладка):
10: int SimpleFunc (const int X, const int Y)
11: {
00401020 push ebp
00401021 mov ebp,esp
00401023 sub esp,40h
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-40h]
0040102C mov ecx,10h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
12: return (X + 3 * Y);
00401038 mov eax,dword ptr [ebp+0Ch]
0040103B imul eax,eax,3
0040103E mov ecx,dword ptr [ebp+8]
00401041 add eax,ecx
13: }
00401043 pop edi
00401044 pop esi
00401045 pop ebx
00401046 mov esp,ebp
00401048 pop ebp
00401049 ret
Вы можете видеть, что есть только 4 инструкции для тела функции, но 15 инструкций только для служебных функций, не включая еще 3 для вызова самой функции. Если все инструкции занимают одно и то же время (но не делают), тогда 80% этого кода являются служебными.
Для такой простой функции, как эта, велика вероятность того, что код служебной функции займет столько же времени, сколько и само тело основной функции. Когда у вас есть тривиальные функции, которые вызываются в теле глубокого цикла миллионы / миллиарды раз, тогда издержки вызова функции начинают становиться большими.
Как всегда, ключом является профилирование / измерение, чтобы определить, дает ли встраивание определенной функции какой-либо чистый прирост производительности. Для более «сложных» функций, которые не называются «часто», выгода от встраивания может быть неизмеримо мала.