2014-07-21 38 views
1

出於可讀性起見,我很喜歡在C/C++,例如:是否寫入布爾條件「完全」折衷表現?

if (foo == true)代替if (foo)if (foo == false)和代替if (!foo)寫布爾條件「完全」。

這會影響性能嗎?

+7

正在運行的程序的性能?還是那個不好的維護程序員試圖通過外部噪聲來讀取邏輯? –

+7

您爲了可讀性而使用的樣式會影響可讀性。 –

+0

@MikeSeymour和@DanielDaranas:好的,如果他們不是最好的,我總是願意改變我的做法。你能解釋一下爲什麼你發現'if(!foo)'比'if(foo == false)'更容易閱讀嗎?我發現了!相當容易被忽視。 – MGA

回答

2

至於直C被而言,這兩種形式的可以結果在不同的機器代碼,其中可以影響性能。 之間的性能差異是否取決於代碼的功能和性能要求。

使用gcc 4.1。2在SLES 10上,我得到了稍微不同的機器代碼if (foo == false) vs if (!foo);給出下面的源代碼:

if (foo == false) 
{ 
    printf("foo is false\n"); 
} 

if (!foo) 
{ 
    printf("foo is 0\n"); 
} 

我得到以下的機器代碼(gcc -S -std=c99 -pedantic -Wall -Werror):

 movb $0, -1(%rbp)  ;; foo = false 
     cmpb $0, -1(%rbp)  ;; if (foo == false) 
     jne  .L6    ;; { 
     movl $.LC2, %edi  ;; 
     call puts    ;; printf("foo is false\n"); 
.L6:        ;; } 
     movzbl -1(%rbp), %eax ;; if (!foo) 
     xorl $1, %eax 
     testb %al, %al 
     je  .L8    ;; { 
     movl $.LC3, %edi  ;; 
     call puts    ;; printf("foo is 0\n"); 
.L8:        ;; } 
     movl $0, %eax 

對於這個特殊的平臺,編譯器,代碼,並設置編譯器選項if (!foo)可風后者比if (foo == false) 慢一點。

現在,對於真正的問題:性能差異(如果存在)是否有關係?對於這個特定的程序,絕對不是;測試在程序的整個生命週期中都會發生一次,並且執行I/O所用的時間將大大多於執行測試的時間。在一個不同的程序中,這個測試在CPU綁定的緊密循環中執行了數千次或數百萬次,那麼它可能會有很大的影響。

可讀性代碼第一; if (foo)if (!foo)表單往往是簡單布爾測試的慣用語言,這就是大多數C和C++程序員期望看到的。話雖如此,如果您覺得它更好地傳達了代碼的意圖(或者您決定將TRUE定義爲0並且FALSE爲1,無論出於何種原因),那麼編寫if (foo == TRUE)if (foo == FALSE)絕對沒有錯。

作出這樣的決定基於性能除非

  1. 你不能滿足硬盤性能要求;
  2. 您已經優化了算法以及適當的數據結構;和
  3. 分析顯示特定語句是剩餘的瓶頸。


1.或不;這取決於需要多少個週期xorltestb要求vs cmpb以及直接訪問寄存器%eax的速度比計算-1(%rbp)要快多少,並訪問得到的位置;就我所知,這是一種洗滌。

3

假設foo是一個bool,它不會。它可以由編譯器進行簡單優化。

但是,如果foo是一個類,它可能會重載運算符來執行任何想要的操作。

+1

現在,這將是有趣的。用無關的語義重載'operator!'和'operator ==(bool)'。 (但我推測他在談論'boo'類型的'foo'。) –

+0

謝謝。我有興趣知道爲什麼編譯器需要優化,如果'foo'是一個布爾值? – MGA

+2

@JamesKanze:大家都樂意去查看所有的常規和常識...... – Deduplicator

-4

假設foo是一個bool,它不。它可以由編譯器進行簡單優化。

但是,如果foo是一個類,它可能會重載運算符來執行任何想要的操作。

+3

爲什麼你剛纔複製@ neilkirk的答案逐字? – juanchopanza

+1

複製自@ Neil-Kirk。 – MGA

+1

投票刪除。 – Caleb

1
if(foo == true) 

即使與邪惡重載它可以有不同的語義和性能比更地道,因爲更簡潔

if(! foo) 

,王氏理智類型和合理高效的編譯器,它應該產生完全相同的相同的原生指令。

如果您允許惡意超負荷,則無論如何所有投注都將關閉,您將遇到應有的麻煩。

儘管如此,以上並不是總是添加明確比較的愚蠢行爲的典型例子。
這將是:

if(foo) 
if(foo == true) 
if((foo == true) == true) 
// ... 

缺點是:

  • 不用贅言,澄清什麼。
  • 遺忘一個= -sign的危險,所以試圖分配值。
  • 「澄清」多少會足夠清楚?
  • 如果不使用布爾常量的關鍵字,而是使用底層的0和1,那麼這樣做有可能會將等於1的等級比較爲1,其中需要不等於0。

請注意,在C,C++和一些相關語言中,同樣適用於指針,整數(包括字符類型)和大多數用戶定義的類型。