我有這段代碼用於測試 switch 語句與函數指針的行為:
#include <stdio.h>
#include <time.h>
int mySum(int startingValue)
{
return startingValue += 1;
}
int mySub(int startingValue)
{
return startingValue -= 1;
}
int main()
{
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
printf("USING SWITCH\n");
printf("Start time: %s", asctime(timeinfo));
int startingValue = 25;
int currentOperation = 0;
// Using switch
for (long long i = 0; i < 10000000000; i++)
{
switch (currentOperation)
{
case 1:
startingValue = mySum(startingValue);
break;
case 0:
startingValue = mySub(startingValue);
break;
}
if (currentOperation)
currentOperation = 0;
else
currentOperation = 1;
}
printf("Result is: %d\n", startingValue);
time(&rawtime);
timeinfo = localtime(&rawtime);
printf("End time: %s", asctime(timeinfo));
printf("\n\n\n");
time(&rawtime);
timeinfo = localtime(&rawtime);
printf("USING FUNCTION POINTERS\n");
printf("Start time: %s", asctime(timeinfo));
startingValue = 25;
currentOperation = 0;
// Using function pointers
int (*mySwitchOfFunctionPointers[2])(int x);
mySwitchOfFunctionPointers[0] = &mySub;
mySwitchOfFunctionPointers[1] = &mySum;
for (long long i = 0; i < 10000000000; i++)
{
startingValue = (*mySwitchOfFunctionPointers[currentOperation])(startingValue);
if (currentOperation)
currentOperation = 0;
else
currentOperation = 1;
}
printf("Result is: %d\n", startingValue);
time(&rawtime);
timeinfo = localtime(&rawtime);
printf("End time: %s", asctime(timeinfo));
return 0;
}
輸出是這樣的,所以代碼使用 switch 語句立即執行,但它需要很多秒的函數指針:
USING SWITCH
Start time: Mon Oct 25 18:04:06 2021
Result is: 25
End time: Mon Oct 25 18:04:06 2021
USING FUNCTION POINTERS
Start time: Mon Oct 25 18:04:06 2021
Result is: 25
End time: Mon Oct 25 18:04:34 2021
編譯為
gcc -c main.c -o test.o -O3 -Wall -Wno-unused -std=c99
gcc test.o -o test
為什麼第二種方法比第一種方法慢???代碼有問題嗎?任何的想法?
編譯器可以內聯開關,然後優化器足夠聰明,可以意識到您的整個循環是空操作,因此將其優化。它不會使用函數指針來做到這一點。見https://godbolt.org/z/qxxoof5cn
如果您將代碼更改為編譯器無法優化的內容,那麼您將獲得非常不同的結果。例如:
int mySum(int startingValue)
{
return startingValue += rand();
}
int mySub(int startingValue)
{
return startingValue -= rand();
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句