2011-12-13 57 views
2

我想計算嚴格正整數的上限的劃分。我有以下兩種實現方式之間進行選擇:用lambda重新定義函數或調用標準API(Math.Ceiling)

var ceil = new Func<int, int, int>((a, b) => a % b > 0 ? a/b + 1 : a/b); 
var x = ceil(y, z); // y and z being int previously defined 

var x = (int)Math.Ceiling((double)y/(double)z); 

這第二個版本(Math.Ceiling)似乎是一樣的作爲第一個(具有拉姆達),但3已添加轉化。所以我想用第一個。我錯過了什麼嗎?

(編輯以精確的事實,它的意思是隻能用嚴格的正整數處理)

+0

爲什麼這裏使用lambda?爲什麼不使用正常的功能? –

+5

我懷疑你會看到任何顯着的性能下降與轉換。再加上'Math.Ceiling'在意圖方面更具可讀性。我不會優化,直到你知道這是一個有問題的代碼段。 –

+0

@Konrad我不確定要理解你的問題。你是說第二個版本是那個還是你在想別的東西? – Hugo

回答

6

就個人而言,我會避免擔心優化了int - >double轉換,這些通常是最少的你擔心表現。是的,他們可以加起來,但你需要在緊密的循環或類似的事情上做很多事情。

我會堅持Math.Ceiling(),因爲這是非常明顯的你想要做什麼,因此更容易維護。如果你發現你的代碼很慢,那麼首先優化並攻擊最大的麻煩點。

這些計時超過1十億迭代,這是8677毫秒Lambda和9,749毫秒Math.Ceiling(),但這是0.0000087 ms和每次通話是可以忽略不計0.0000097毫秒。

+0

請注意,這可能不是蘋果對蘋果的比較。例如,抖動可以內聯調用Math.Ceiling,但不能內聯委託調用。 –

+0

@EricLippert:好點。只是爲了澄清我沒有表現出時間來說,「嘿,lambda更快!使用它!」但是爲了表明這一點 - 粗略地說 - 它們在性能上非常接近,以至於它是一個非常小的優化(如果有的話),並且在這個過程中失去了一些可讀性。 –

+0

純粹是對那些對內部有好奇的人提出的問題,但@EricLippert是否知道它是否可以內聯調用Math.Ceiling,這是'extern'? –

0

沒有理由使用lambda代替方法。

第二個有點難看:當分數是除數的整數倍時,您依靠浮點除法來給出精確的結果。雖然我無法想象32位整數的情況,如果情況並非如此,但它仍然給我一種不好的感覺。如果您以後用Int64替換Int32,它突然不再正確。

只要定義一個新的正常的方法:

public static int IntDivisionCeiling(int dividend, int divisor) 
{ 
    int quotient=dividend/divisor; 
    if(dividend%divisor>0) 
    return quotient; 
    else 
    return quotient+1; 
} 
+0

我覺得沒有錯誤。如果商數是負數,那麼餘數也是。 –

+0

@Eric你說得對。我錯誤地認爲'>'爲'==',並且對'then'和'else'部分不太注意。 – CodesInChaos