2013-10-18 67 views
3

我經常被這個困惑。我總是被教過使用變量或常量來命名我常用的數字,但如果它降低了程序的效率,我還應該這樣做嗎?下面有一個例子:使用變量與幻數的性能影響

private int CenterText(Font font, PrintPageEventArgs e, string text) 
    { 
     int recieptCenter = 125; 
     int stringLength = Convert.ToInt32(e.Graphics.MeasureString(text, font)); 
     return recieptCenter - stringLength/2; 
    } 

上述代碼是使用命名變量,但運行速度較慢則此代碼:

private int CenterText(Font font, PrintPageEventArgs e, string text) 
    { 
     return 125 - Convert.ToInt32(e.Graphics.MeasureString(text, font)/2); 
    } 

在這個例子中,在執行時間的差異是最小的,但大約在較大的什麼代碼塊?

+0

發表了同樣的方法兩次,然後忘了把長度除以2.問題現在是正確的。 – Nathan

+1

「可讀性」和「簡潔性」之間有一個主觀的灰色區域........意見會有所不同。 – granadaCoder

+1

我更喜歡第一個,因爲從現在起6個月,有人可能會弄清楚我做了什麼。但是我會爲125和2定義「const」值...............所以這些值意味着什麼......不僅僅是一些隨機的int在那裏掛起。 – granadaCoder

回答

9

使用變量和硬編碼值之間的區別在最壞的情況下可以忽略不計。編譯器很好地處理這樣的事情。如果您發現性能存在差異,我想知道您收集這些指標的方法。 (您的測試本身可能是可疑的,而且很可能不可重複。)

無論如何,您應該首先關心如何讓您的程序正確和可維護。這意味着:

  • 仔細命名你的類,方法和變量
  • 分離關注
  • 避免魔術數字和字符串(到底是什麼125什麼意思?)
  • 避免harcoding

此外,receiptCenter聽起來不像它應該是一個常數。它可能很少改變,但我建議你將它存儲在你的應用程序之外的配置文件或數據庫表等。如果這個值需要改變,你必須重新編譯並推動整個事情。另外,如何在收款中心的價值不同的其他地方發佈您的軟件?您只是想更改配置設置,而不是針對該實例構建不同版本的應用程序。

優化是你最後一件擔心的事情,除非它是你必須擔心的第一件事,而這是建築師/專家級考慮。

+0

我看不出任何過早的優化問題。其餘的肯定是真的。 PS:硬編碼錯字(缺少「c」)。 – JensG

+0

@JensG:謝謝你們的錯誤。對於過早選擇。請仔細重讀OP的標題:「使用變量與幻數相比的性能影響」這就是過早優化的定義,並且非常簡單。另請參閱我的編輯。 –

+0

好的,同意。現在我看到了:-) – JensG

9

當他們說「使用常量」時,他們的字面意思是「使用常數」;它們並不意味着「使用永不改變的變量」。

這相當於代碼:

const int recieptCenter = 125; 
int stringLength = Convert.ToInt32(e.Graphics.MeasureString(text, font)); 
return recieptCenter - stringLength/2; 

隨着地方const關鍵字,編譯器知道125永遠不會改變,並且將能夠應用,它將適用於表達恆定的優化作爲文字。

命名你的「神奇數字」有一個巨大的優勢:在你離開公司後維護你的代碼的人會知道125的含義。它會幫助你,當你在幾年內重新訪問這些代碼的時候。

+2

'當你幾年後回來重訪這些代碼時,它也會幫助你。「 - 甚至幾周。 –

-1

receiptCenter應該是一個常量,在私有方法之外的某個地方聲明,在一些顯而易見的地方,所有常量都是一起聲明的。或者,它可以是從配置中讀取的變量。

當您在類庫內部的某個私有方法的某處爲某個常數編號時,它確實不會改進您的代碼。

+1

如果在一個地方聲明變量的含義,它會添加什麼來增加它們的含義?如果常量只用於一種方法,爲什麼要將聲明和用法分開?爲什麼要從配置中讀取pi的值?一個常量確實可以改善代碼,即使它使用相同的方法進行分解,因爲它增加了數字含義的清晰度。 –

+1

一個示例是配置。即使您僅使用一次該常量,您仍然可能需要稍後更改的選項。如果從配置文件或數據庫中讀取數字,它肯定會讓您的生活更輕鬆。 – JustAndrei

+0

+1,以便從配置中讀取更好。我懷疑這個變量是否符合像Math.PI這樣的真正的常量語義。另外,@ MarkusMeyer:查看一組常量,在.NET的System.Math類中指出您最喜歡的反編譯器,以瞭解Justandrei正在談論的內容。 –