If else 三目運算子 底層實現 效率差異

2021-07-26 05:01:55 字數 3238 閱讀 2767

原文內容:

某日乙個同學在做演算法題,(旅遊揹包)在oj系統提交時超時 我們在設法優化**減少執行時間時,發現貌似if-else比三目運算?: 更快一點。 於是,用vc寫了一段簡短的測試。同樣是雙重迴圈中執行 if-else與三目運算,計算其花費的時間。

a=100,b=50,n為測試變數 

start=clock();

for(i=1;i<=n;i++)

}end=clock();

cout << "time= "

<< end-start << endl;

for(i=1;i<=n;i++)

} 以下是測試結果:

time單位為 ms

n=100

iftime = 0

the :? time = 0

n=1000

iftime = 2

the :? time = 4

n=10,000

iftime = 253

the :? time = 360

n=50,000

iftime = 6209

the :? time = 8941

n=100,000

iftime = 24343

the :? time = 35807

可以見到,隨著n越大,兩者差距越來越明顯(未經多台電腦測試,僅經自己台試,神奇的是在ubuntu下沒多大差別,這問題在後面說),然後我通過反編譯,檢視它們的彙編**,發現一件令我不解的神奇事。

以下分別是if-else與三目運算的彙編**。

37:               if(a>b)

00401079 mov ecx,dword ptr [ebp-10h]

0040107c cmp ecx,dword ptr [ebp-14h]

0040107f jle main+79h (00401089)

38: temp=a;

00401081 mov edx,dword ptr [ebp-10h]

00401084 mov dword ptr [ebp-18h],edx

39: else

00401087 jmp main+7fh (0040108f)

40: temp=b;

00401089 mov eax,dword ptr [ebp-14h]

0040108c mov dword ptr [ebp-18h],eax

51: temp=a>b?a:b;

004010f3 mov edx,dword ptr [ebp-10h]

004010f6 cmp edx,dword ptr [ebp-14h]

004010f9 jle main+0f3h (00401103)

004010fb mov eax,dword ptr [ebp-10h]

004010fe mov dword ptr [ebp-24h],eax

00401101 jmp main+0f9h (00401109)

00401103 mov ecx,dword ptr [ebp-14h]

00401106 mov dword ptr [ebp-24h],ecx

00401109 mov edx,dword ptr [ebp-24h]

0040110c mov dword ptr [ebp-18h],edx

可見後者比前者多了兩條指令。

if-else無論在何種情況下(在if中或者else中),都是通過先將需要賦的變數值傳給暫存器然後再通過暫存器賦值給temp變數 。即

mov edx,b; mov temp,edx ;

然而,對於三目運算,它其中一步卻增加多了乙個臨時變數。

mov ecx,b;mov newtemp,ecx;

mov edx,newtemp;mov temp;edx;

以下是乙個同學給我的答案(他從編譯原理課上學的):

因為三目運算是先運算,再賦值!

例如 :

temp = a > b ? a : b ;

a > b ? a : b 是運算, temp = (a > b ? a : b )是賦值。

所以在三目的彙編裡面 a,b,temp位址 為10h,14h 18h 無論a>b的結果怎樣,都有先將它後 面的結果儲存在位址為 24h 的中間變數裡面 ,然後再 賦值給位址為 18h 的temp變數中!

而 if 語句是直接賦值 ,不存在運算,所以快了一點。
然後根據這原理,可以知道 ++i 比 i++ 快, x+=y 比 x=x+y 快。

不過,我們寫程式的時候可以忽略它們,因為這種東西,編譯器已經幫我們優化了!!!

所以不管你寫 i++ 還是 ++i ,它都是一樣的 ,以下是證明。

00401048 mov dword ptr [ebp-4],1

32:

33: ++i;

0040104f mov eax,dword ptr [ebp-4]

00401052 add eax,1

00401055 mov dword ptr [ebp-4],eax

34:

35: i++;

00401058 mov ecx,dword ptr [ebp-4]

0040105b add ecx,1

0040105e mov dword ptr [ebp-4],ecx

以下是常量的彙編**。 確實沒有跳轉指令 將1:0換成其他數字,經測試也是沒有,雖然指令會多了幾條。

38: z=x>y?1:0;

0040106e mov ecx,dword ptr [ebp-8]

00401071 xor edx,edx

00401073 cmp ecx,dword ptr [ebp-0ch]

00401076 setg dl

00401079 mov dword ptr [ebp-4],edx

Java三目運算子(if else 簡寫)

對於有些選擇分支結構,可以使用簡單的條件運算子來代替.如 if a 可以用下面的條件運算子來處理 min a?a b 其中 a 是乙個 條件表示式 它是這樣執行的 如果a 條件運算子由兩個符號組成 和 要求有3個操作物件,所以也叫它三目運算子,它是c語言中唯一的三目運算子.它的一般形式為 表示式1?...

三目運算子

1 概念 根據不同的條件,執行不同的操作 返回不同的值。條件1?值1 或操作1 如果滿足條件 1,就返回值 1或執行操作1 條件2?值2 或操作2 否則,如果滿足條件 2,就返回值 2或執行操作2 總結 表示式 閏年 平年 多種條件 條件 1?值1 條件2?值 值3例子 1 輸入星期四 就輸出 班級...

三目運算子

單目運算子 3 雙目運算子 3 4 三目運算子 格式 表達關係式 表示式1 表示式2 如果條件為true,運算後的結果是表示式1 如果條件為false,運算後的結果是表示式2 比較表示式 結果是乙個boolean型別 執行流程 根據比較表示式的計算返回乙個true或者false。如果是true,就把...