Performance 质数性能差异ACF与Lucee

Performance 质数性能差异ACF与Lucee,performance,coldfusion,lucee,Performance,Coldfusion,Lucee,以下查找素数的代码在性能方面与Adobe ColdFusion(10)和Lucee(4.5)有很大不同。在同一台机器上测试(6C i7 3930k@4 GHz,Windows 10 64位,两个CFML引擎上的JVM内存设置相同:JDK7-Xms512m-Xmx2048m-XX:MaxPermSize=512m): ticks=getTickCount(); 停止指数=10000; 素数=[]; 分区=0; 添加(2); 添加(3); n=5; 对于(n;n

以下查找素数的代码在性能方面与Adobe ColdFusion(10)和Lucee(4.5)有很大不同。在同一台机器上测试(6C i7 3930k@4 GHz,Windows 10 64位,两个CFML引擎上的JVM内存设置相同:JDK7
-Xms512m-Xmx2048m-XX:MaxPermSize=512m
):


ticks=getTickCount();
停止指数=10000;
素数=[];
分区=0;
添加(2);
添加(3);
n=5;
对于(n;n

#numberFormat(arrayLen(primes))#下面是质数#numberFormat(stopIndex)#。

10k时的停止指数

  • ACF:280毫秒
  • 吕克:1300毫秒
20k时的停止指数

  • ACF:1000毫秒
  • 吕克:4800毫秒
30k时的停止指数

  • 空气流量:2200毫秒
  • LUC:10500毫秒
trycf.com
cflive.net
显示了类似的差距

我检查了cfscript(与标签)是否对时间有影响,但没有。CFML引擎相关的服务器设置似乎也没有任何明显的影响

性能差异的原因是什么?
我怎样才能解决这个问题?


背景:我在一台生产服务器上运行大量的数学运算(几何、图像渲染),这台服务器恰好运行Lucee,并注意到性能缓慢。

我认为性能问题的解决取决于Lucee,而不是你和你的代码

然而,从这个特定算法的整体性能来看,你能做的最经济的事情是循环到
sqr(n)+1
,而不是一直循环到
n
。您所做的工作远远超出了需要,这比平台差异对代码性能的贡献更大

此外,您只需要循环前面的素数,而不是每(秒)个数。那会进一步提高你的表现


我意识到该算法只是一个例子,但老实说,它的其余部分是不可能修复的。向Lucee提交一张罚单,等待它被修复(或者DIY,如果你有时间/Java知识)。

整数数学比浮点数学慢,所以它运行得慢,因为Lucee将变量存储为类型。如果强制n为非整数,Lucee的运行速度将提高4倍

if ((n+1.0) % d == 0) {
这一调整也使ACF的速度提高了一倍多


我知道这并不是在回答问题,但进一步看亚当的评论,它甚至不必是平方根。一旦你意识到一个数字不能被3整除,你可以将你的top限制为被3整除的结果。当n变大时,跟踪以前的素数会占用内存。如果你能负担得起,那太好了。如果不能,那么将分母增加2将使其速度提高2,因为您跳过了偶数。此代码大约快50倍:

<cfscript>
    ticks = getTickCount();
    stopIndex   = 10000;
    primes      = [];
    divisions   = 0;
    primes.add(2);
    primes.add(3);
    n = 5;
    for (n; n < stopIndex; n += 2) {
        isPrime = true;
        d=3;
        n2=n;
        for (d; d < n2; ) {
            divisions++;
            Result=n/d;
            if (Result eq Int(Result)) {
                isPrime = false;
                break;
            } else {
              d+=2;
              n2=Result;
            }
        }
        if (isPrime) {
            primes.add(n);
        }
    }
    ticks = (getTickCount() - ticks);
</cfscript>

ticks=getTickCount();
停止指数=10000;
素数=[];
分区=0;
添加(2);
添加(3);
n=5;
对于(n;n
32毫秒内56570个分区(与我的机器上以前的1500个分区相比)


1229个素数低于10000。

在执行过程中进行堆栈跟踪,查看哪些代码运行得最快。另外,请分析VM上的内存使用情况,看看是否不同。@alex感谢您提出这个问题。我一直在与Lucee团队讨论这一点,我们将更深入地了解ACF和Lucee之间存在这种性能差异的原因,并了解Lucee是否有任何性能改进。
<cfscript>
    ticks = getTickCount();
    stopIndex   = 10000;
    primes      = [];
    divisions   = 0;
    primes.add(2);
    primes.add(3);
    n = 5;
    for (n; n < stopIndex; n += 2) {
        isPrime = true;
        d=3;
        n2=n;
        for (d; d < n2; ) {
            divisions++;
            Result=n/d;
            if (Result eq Int(Result)) {
                isPrime = false;
                break;
            } else {
              d+=2;
              n2=Result;
            }
        }
        if (isPrime) {
            primes.add(n);
        }
    }
    ticks = (getTickCount() - ticks);
</cfscript>