2013-10-06 103 views
2

我在考慮更多我的程序現在將使用多少系統內存。我目前在大學做一級計算,我知道在大多數程序中,差異可以忽略不計,但我想知道下列實際上是否在任何語言中都有所不同。If語句中的內存效率

說我想輸出「真」或「假」取決於條件是否爲真。就個人而言,我更願意做這樣的事情:

Dim result As String 

If condition Then 
    Result = "True" 
Else 
    Result = "False" 
EndIf 

Console.WriteLine(result) 

不過,我想知道,如果下面將消耗更少的內存,等:

If condition Then 
    Console.WriteLine("True") 
Else 
    Console.WriteLine("False") 
EndIf 

顯然,這是一個很大大簡化例子,在我的大多數情況下,還有更多需要輸出的信息,而且我意識到在大多數商業程序中,這類陳述很少見,但希望你能得到原則。

我在這裏關注VB.NET,因爲這是用於該課程的語言,但真的我很想知道這在不同的編程語言中有何不同。

+0

正如dasblinkenlight所說,除非在特定情況下(高內存要求複雜系統),否則內存現在不是問題。無論如何,你應該把你的記憶力最大化的努力集中在其他方面,這可能會得到更多的關注效果。中間變量的聲明(這裏的「結果」)幾乎沒有任何影響(你正在實例化給定類,字符串;在寫第二個代碼的時候也是「True」/「False」)。有些人傾向於將代碼的長度與實際的性能/內存利用率等聯繫起來,這兩種情況都沒有關係... – varocarbas

+0

...打算優化代碼的編寫方式(並且構建程序以使內存開銷爲儘可能低)毫無疑問是一件好事,但你應該把重點放在真正重要的事情上(做一些關於高度記憶消耗實踐的研究),並且有一個想法很明確:從代碼的大小你不能獲得任何有價值的信息;做一些研究或者實施一種確定內存消耗的方法,如果你想知道每一點「昂貴」是多少。 – varocarbas

+0

@varocarbas感謝您的意見。我看到你的觀點,我認爲這將是關於聲明中間變量的情況......我知道示例代碼的大小意味着沒有什麼是真正相關的,但是它只是將我想要問的概念。 – Andy

回答

3

使if快或慢的主要問題是可預測性。

現代的CPU(2000年以後的任何東西)使用mechanism called branch prediction
先閱讀上面的鏈接,然後閱讀以下內容......

哪個更快?
if語句構成一個分支,因爲CPU需要決定是關注還是跳過if部分。
如果它正確地猜測分支跳躍將執行0或1個週期(1Ghz計算機上1納秒)。
如果它沒有正確猜測分支,則跳躍將需要50個週期(給定或取出)(微秒的1/200)。

因此,即使感覺到這些差異作爲人類,您也需要執行if語句數百萬次。

這兩個語句以上有可能在完全相同相同量的時間來執行,這是因爲:

  1. 將值分配給變量取忽略不計的時間;在多分量CPU上平均少於一個CPU週期*。使用常量參數調用函數需要使用不可見的臨時變量;所以很可能代碼A編譯成與代碼B幾乎完全相同的目標代碼。

*)所有當前的CPU都是多分量的。

消耗更少的內存
如上所述,兩個版本需要把布爾到一個變量。
版本A使用明確的版本,由您聲明;版本B使用由編譯器聲明的隱式版本。

但是版本A保證只有一個調用函數WriteLine
雖然版本B可能(或可能不)有兩個調用函數WriteLine
如果編譯器中的優化器是好的,則代碼B將被轉換爲代碼A,如果不是,它將保留在冗餘調用中。

是多麼糟糕的浪費
通話大約需要10個字節的字符串的分配(每Unicode的字符2個字節)。
但其他版本也是如此,所以也是如此。
爲呼叫留下5個字節。另外可能需要一些額外的字節來設置堆棧。
所以,讓我們說由於你的代碼完全可怕,你現在浪費了10個字節。

沒什麼好擔心的。

從可維護性的角度來看
計算機代碼是爲人類而不是機器寫的。
所以從這個角度來看,代碼A顯然是優越的。 想象一下,不要在2個選項 - 真或假 - 而是20之間進行選擇。
您只能調用一次該功能。
如果您決定改變WriteLine的其他功能,您只需在一處改變它,而不是兩個或20個。

如何加快速度?
有兩個值幾乎是不可能的,但如果你有20個值,你可以使用查找表。
很明顯,優化是不值得的,除非代碼得到執行很多次。

+0

+1謝謝你的回答。分支預測非常有趣,並提供了進一步的證據來支持代碼A.感謝您的思考 – Andy

2

如果您需要知道指令要執行的精確內存量,您可以在代碼上使用ildasm,然後親自查看。但是,如果內存非常便宜且豐富,並且編譯器足夠智能以查看常見模式並減少它們生成的代碼量,那麼代碼所消耗的內存量就會少得多。

更重要的是您的代碼的可讀性:如果複雜的條件鏈總是會導致打印條件設置的結果,那麼您的第一個代碼塊將以比第二條代碼更乾淨的方式表達此想法。在其他方面相同的情況下,您應該更喜歡任何您認爲最具可讀性的代碼形式,並讓編譯器擔心優化。

P.S.不用說Console.WriteLine(condition)會產生相同的結果,但這當然不是您問題的要點。

+0

+1感謝您的回答。我會看看'ildasm',但是因爲我提供的示例代碼確實毫無意義。 – Andy