2011-12-13 59 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