2010-03-05 82 views
15

blog爲C#方法添加return語句是否可以提高性能?

12),包括與在函數/方法return語句。 它如何提高性能 顯式使用返回允許JIT執行稍微更多的優化。沒有return語句,每個函數/方法都會在堆棧上被賦予幾個局部變量,以透明地支持沒有關鍵字的返回值。保持這些使得JIT難以優化,並且會影響代碼的性能。查看你的函數/方法並根據需要插入返回值。它根本不會改變代碼的語義,它可以幫助您從應用程序中獲得更多的速度。

我相當確信這是一個虛假陳述。但是想讓那裏的意見專家出來。你們有什麼感想?

+4

的確看起來很腥,但我會讓JIT大師的體重加入! – mjv 2010-03-05 15:38:54

+4

還有更多可疑的陳述。 「使用'ArrayLists'代替數組」,「使用ValueTypes設計」。我的意思是,ArrayLists?這對拳擊很棒。並且知道何時使用結構而不是類是許多事情,即使不是大多數人混淆 - 包括我在內。奇怪的「小費」。 – Razzie 2010-03-05 15:47:50

+0

沿着@ Razzie的評論,我會採取一個鹽的糧食,它沒有考慮甚至在.NET 2.0天添加的項目... – 2010-03-05 15:53:30

回答

10

此聲明不適用於C#。使用C#你必須明確地設置一個「return」來有一個有效的函數,沒有返回,你會得到一個編譯錯誤,並不是所有的代碼路徑都返回一個值。

隨着VB.NET這將適用,因爲VB.NET沒有明確的返回的要求,並允許你有函數,永遠不會返回一個值,以及允許您設置返回使用的名稱功能。

爲了提供一個例子

在VB.NET,你可以做到這一點

Function myFunction() As String 
    myFunction = "MyValue" 
End Function 

Function myFunction2() As String 
    'Your code here 
End Function 

以上編譯,也沒有用明確的「收益」,有參與這個更多的開銷。

如果你嘗試用C#

string myFunction() 
{ 
    //Error due to "Cannot assign to 'myFunction' because it is a 'Method Group' 
    myFunction = "test"; 
} 

string myFunction2() 
{ 
    //Error due to "not all code paths return a value 
} 

要做到這一點我的評論指出,你得到的錯誤。

+0

...親自? – Svish 2010-03-05 15:41:53

+0

是的,刪除了....它已經是一個很長的早晨了...... – 2010-03-05 15:45:00

+0

我從博客中讀到OP的引用文本,意思是使用返回語句來處理短路處理,就像Nick猜測的一樣。 – chsh 2010-03-05 17:41:38

1

我唯一的猜測就是他說的是VB.NET而不是C#。 VB.NET允許你這樣事返回值

Public Function GetSomething() As Int 
    GetSomething = 4 
End Function 

雖然我的VB是令人難以置信的過時。這可能會比使用顯式返回語句要慢

+0

此外這篇文章:http://stackoverflow.com/questions/451025/vb-net-function-return談論性能和VB.Net中的Return語句:il生成似乎幾乎相同,速度是相同的。 (我自己沒有做過反彙編,但是在這個問題中提出的那個似乎是合乎邏輯的) – 2010-03-05 15:42:44

+0

@dotjoe:怎麼樣?這實際上對於在C#中必須聲明一個'result'(或類似的)變量的情況非常有用。就我個人而言,我完全適應了C#風格,但我無法形成一個令人信服的理由,爲什麼VB風格應該更糟。對我而言,這只是一個習慣問題,VB的做法是完全合理的。 – 2010-03-05 16:07:45

+0

@Konrad Rudolph等待...這個語法和'Return 4'不一樣嗎?它是否保持結果直到函數結束並可以多次設置? – dotjoe 2010-03-05 16:14:02

4

該帖子有點模糊。作爲一名C#開發人員,我的第一個想法是「相對於什麼?」。然而,他可能指的是這樣的:

public bool MyFunction() 
{ 
    bool result = false; 
    if (someCondition == true) 
    { 
     // Do some processing 
     result = true; 
    } 
    else if (someOtherCondition == true) 
    { 
     // Do some processing 
     result = true; 
    } 
    // ... keep going 

    return result; 
} 

他可能會被提示與return true;更換result = true;陳述可能有更好的表現。我個人並不確定......在那個時候,這與JIT理論相當深入,我認爲與你可能做出的其他性能改進相比,所取得的收益將是非常小的。

+0

同意這一點 - 這是您必須決定可維護性比微不足道的性能收益更重要的時代之一! – Fenton 2010-03-10 08:57:02

0

通常有2個點我退出一個函數。 在我的方法一開始就驗證輸入的數據:

if (myParameter == null) 
    throw new ArgumentNullException("myParameter"); 

和/或方法的盡頭。


private bool GetSomeValue() 
{ 
    bool returnValue = false; 
    // some code here 
    if (some condition) 
    { 
     returnValue = some expression 
    } 
    else 
    { 
     returnValue = some other expression; 
    } 
    return returnValue; 
}

我沒有返回條件內部的原因是,這樣有1個退出點的功能,它有助於調試。沒有人希望維護一個包含12個返回語句的方法。但這只是我個人的觀點。我會在可讀性方面犯錯,而且不用擔心優化,除非您處理實時的必須更快的情況。

+4

IMO的單一返回點概念在現代軟件中無關緊要。我寧願馬上看到return語句,並知道退出的代碼,而不是想知道returnValue是否會在方法的其他地方被操縱,如果你可以從這些if塊中返回的話。 – 2010-03-05 16:18:10

+1

@ChrisMarisic - 我同意。 multiple-returns-is-bad參數會將* noise *添加到代碼中。如果你不得不返回5個地方,那麼不可能比分支5種方式更糟糕,因爲可能的讀者沒有遵循意圖而可能改變狀態。 – Kit 2011-10-12 18:25:30

+0

@Kit我不得不閱讀你的評論幾次,以確保我瞭解它。我同意你的看法,當你可以立即返回時,選擇延遲返回**將**添加噪聲代碼。 – 2011-10-13 14:36:14

2

這對VB.NET和C#都有些不錯。在C#中,程序員必須明確聲明保存返回值的變量,它在VB.NET中是自動的。大多數返回值都在EAX或RAX寄存器中返回,JIT編譯器必須生成代碼,以便在函數退出之前從返回值變量中加載寄存器。當您使用return語句時,JIT編譯器可能有機會直接加載EAX寄存器,或者已經擁有包含正確值的寄存器,並跳過函數退出代碼,繞過了從變量加載指令。

這是一個相當大的「可能」順便說一句,真正的代碼總是用if()語句測試一些表達式。評估表達式幾乎總是涉及到使用EAX寄存器,它仍然需要用返回值重新加載。與x86編譯器相比,x64 JIT編譯器的工作完全不同,後者似乎總是在我進行的一些抽查中使用該變量。因此,除非您在64位版本的Windows上運行,否則您不可能領先。

在過早優化的所有邪惡中,這一個可以說是最糟糕的。節省的潛在時間很少,首先編寫清晰的代碼。稍後再簡介。

+0

有一種情況是返回語法簡化了編譯器,它是尾調用遞歸優化,因爲當返回調用在這時稍微容易些,因爲不需要跟蹤代碼的其餘部分來查找調用是尾 - 遞歸與否(只要查找跳轉到方法體的末尾)。但是我不知道關於這個特定情況的JIT編譯器的當前狀態,所以它甚至可能不成問題。 – 2010-03-05 17:00:40

+0

骯髒的小細節!這就是我正在談論的.. 謝謝nobugz :) – HashName 2010-03-05 18:27:06

3

我不同意 - 我認爲每種方法中的單個輸入和單個輸出都會使代碼更容易閱讀和調試。函數中的多個返回語句可以使導航代碼更具有通用性。實際上(如果可能重構),比具有多個出口的較大函數更適合具有更小的函數。