CFM与CFC中的范围访问性能

5
我知道这个问题可能有点学术性,但我只是想理解ColdFusion中的这种行为。
在CFM上访问REQUEST作用域比在方法中访问REQUEST作用域所需的时间更短。据我观察,查看我的.class文件时唯一的区别是,在方法内部,它必须引用CFPage参数来访问structKeyExists()方法以检查REQUEST范围。此外,另一个奇怪的现象是,在CFC的方法中访问THIS作用域比访问VARIABLES作用域更快。
有人知道这是为什么吗?
index.cfm
<cfscript>

tests = new tests();

request.test = {
    "foo":[1]
};

iterations = 10000;

starttime = getTickCount();
for( i=1; i<=iterations; i++){
    if( structKeyExists( request, "test" ) ){
        request.test.foo[1];
    }
}
writeoutput( "REQUEST scope access on CFM: " & getTickCount()-starttime & "<br>" );
tests.test( iterations ) ;
</cfscript>

Test.cfc

component{

function test( iterations ) {
    // test variables
    variables.testvar = {foo : [1]};
    this.testvar = {foo : [1]};

    var startTime = getTickCount();
    for( var i=1; i<=iterations; i++){
        if( structKeyExists( request, "test" ) ){
            request.test.foo[1];
        }
    }
    writeOutput( "REQUEST scope access in method: " & getTickCount()-startTime & "<br>" );

    startTime = getTickCount();
    for( i=1; i<=iterations; i++ ){
        if( structKeyExists( variables, "testvar" ) ){
            variables.testvar.foo[1];
        }
    }
    writeOutput( "VARIABLES scope access in method: " & getTickCount()-startTime & "<br>" );

    startTime = getTickCount();
    for( i=1; i<=iterations; i++){
        if(structKeyExists(this, "testvar" ) ){
            this.testvar.foo[1];
        }
    }
    writeOutput( "THIS scope access in method: " & getTickCount()-startTime & "<br>" );


}

有趣的是,当键存在时,isNull()比structKeyExists()更快。然而,当变量不存在时,structKeyExists()更快。


我并不是故意要表现得迟钝(真的不是),但实际问题是什么?它只是类似于“为什么”这样的问题吗? - Adam Cameron
3
哈,亚当,你太客气了。我原以为会有更多的热情呢!是的,这只是一个“为什么?”问题。我明白如果这种问题会让一些人感到厌烦,但这更多是出于好奇。我一直在自己思考这个答案。我在我的问题中加了一个“为什么”。 - J.T.
是的,Scott,它确实有影响!然而,这并没有阻止开发人员将其放入其中。此外,THIS与VARIABLES的性能之间的区别令人困惑。 - J.T.
在那时,请求指针的副本将被放置到本地作用域中,这应该使它的速度与访问本地/参数相同。 - J.T.
让我们在聊天中继续这个讨论 - J.T.
显示剩余7条评论
1个回答

1
这不是回答你“为什么?”的问题,而是一个不同的“为什么?”
你为什么在意呢?我是指在现实世界中。为什么要在StackOverflow上提问。
我认为这是个很好的问题(也是我着迷的事情),但我会在博客上写这种东西,这是我的爱好。
然而从日常工作的角度来看,在我开始关注任何这种事情之前,我会评估性能差异有多大?如果,举例来说,你需要循环运行代码1000000次才能放大它足以看到使用请求范围比使用传递引用慢两倍(比如2000ms)的有意义结果,那么重要的不是100%的差异,而是每次迭代只有0.001毫秒的差异:也就是说,这根本没有关系。
我发表这个答案并不一定是为了你,而是为了以后的人:要谨慎进行微观/过早优化。这种事情很少会是你真正需要优化的原因。
与此同时……你在Railo上运行了测试吗?是否有任何差异?

如果你能把所有发现都写成博客就太酷了!


Adam,我喜欢你的博客,经常阅读旧文章以保持信息的新鲜度。然而,我不认为我能够维护自己的博客。我的当前项目让我调整一个相当复杂的高容量过程,这个过程已经针对除了完全重写之外的所有标准内容进行了调整。在这次调整之后,我们将转向Java,这将是昂贵的。所以,在这一点上,我基本上追求每微秒的时间。我完全同意,在大多数情况下,即使对于我们来说,这些优化可能是最后考虑的。这是一个特殊情况。 - J.T.
1
好的。这听起来像是那些罕见情况之一,这并不是过早优化。如果你想写点东西,随时发给我,我会在我的博客上以你的名义发布。这对社区来说将是有趣的内容。当然,如果你对此不感兴趣,也没关系! - Adam Cameron
同时,了解CF执行操作所需的时间基准是非常有趣的事情。例如,Java JIT编译器将采取漂亮干净的本地JAVA类和许多小函数,并将它们内联到一个巨大的函数中以保持代码更快的事实对我们来说是一个巨大的损失,因为编译器只能将每个方法作为CFML类架构处理。因此,在ColdFusion中编写具有许多小函数的“干净”代码可能对某些高容量操作不利。真的很酷去学习。 - J.T.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接