0

我有这个锡兰代码:

Integer fact(Integer n)
{
    return (n<=1)then 1 else n*fact(n-1);
}
Integer? factorial(Integer|String|Null n)
{
    Integer? num;
    if(is String n)
    {
        num=parseInteger(n);
    }
    else if(is Integer n)
    {
        num=n;      
    }   
    else
    {
        num=null;
    }
    if(exists num)
    {
        if(num<0)
        {
            return null;
        }
        if(num==0)
        {
            return 1;
        }
        return (2..num).fold(1)((x,y)=>x*y);//line 1
    }
    else
    {
        return null;        
    }       
}
shared void main() 
{
    print("enter a number");
    value input=process.readLine()?.trimmed;
    value starttime=system.milliseconds;
    value fact=factorial(input);
    value elapsedtime=(system.milliseconds-starttime).float/1000;
    if(exists fact)
    {
        print("(!n)=``fact``");
        print(elapsedtime);
    }
    else
    {
        print("Error, either you gave a negative number or you didn't enter an integer(or did you left the input blank ?)");
    }   
}

在第 1 行,我使用 fold 来计算阶乘,得到的性能在 0.08 到 0.06 秒之间。

现在,如果我用这个替换第 1 行:

return fact(num);

我的性能介于 0.021 和 0.012 之间,这是为什么呢?

在这种情况下,我尝试的数字是 10。

4

1 回答 1

5

先说几点:

  • 不要system.milliseconds用于小测量,它是出了名的不精确(它的最大分辨率是 1/60 秒或大约 16 毫秒),请system.nanoTime改用

  • 对于 Java VM,这是一个太小的基准,无法说出任何有价值的东西,VM 需要在进行任何优化之前“预热”。请参阅如何在 Java 中编写正确的微基准测试?了解更多信息

但除此之外,它fact()可能更快的一个原因是因为它的代码在内部进行了优化以使用 Java 原始类型,而它fold()是一个通用函数,这可能意味着正在进行大量的装箱操作。

Integer现在,在处理诸如此类的基本类型时,Ceylon 还不太擅长优化具有泛型参数或返回类型的函数Float。希望在未来的版本中,我们能够在一定程度上弥补这一点。

于 2015-07-25T14:24:01.897 回答