我有這段代碼用于測驗 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
為什么第二種方法比第一種方法慢???代碼有問題嗎?任何的想法?
uj5u.com熱心網友回復:
編譯器可以行內開關,然后優化器足夠聰明,可以意識到您的整個回圈是空操作,因此將其優化掉。它不會使用函式指標來做到這一點。見https://godbolt.org/z/qxxoof5cn
如果您將代碼更改為編譯器無法優化的內容,那么您將獲得非常不同的結果。例如:
int mySum(int startingValue)
{
return startingValue = rand();
}
int mySub(int startingValue)
{
return startingValue -= rand();
}
uj5u.com熱心網友回復:
編譯器優化引數 (-O3) 負責這種行為。
編譯器可以for在switch內部優化第一個-Loop ,因為它具有關于此代碼的所有所需資訊。
不幸的是,編譯器不能用函式指標優化代碼。由于編譯器不知道呼叫了哪些函式。
如果在編譯時洗掉 -O3 引數,您將看到,函式指標和switch-case陳述句需要相似的時間。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/336482.html
下一篇:如何在C中“多載”scanf?
