Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope Access Performance in CFM vs. CFC

Tags:

coldfusion

I understand that this question might be slightly academic, but I am just attempting to understand this behavior in ColdFusion.

When accessing the REQUEST scope on a CFM, it takes less time than accessing the REQUEST scope in a method. The only difference, as far as I can tell, when looking at my .class files is that, inside a method, it has to reference the CFPage argument to access the structKeyExists() method to check the REQUEST scope. In addition, another oddball, is that accessing the THIS scope is faster than accessing the VARIABLES scope in a method in a CFC.

Does anyone know why this might be the case?

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>" );


}

Just a fun aside -- isNull() is faster than structKeyExists() when the key exists. However, structKeyExists() is faster when the variable doesn't exist.

like image 924
J.T. Avatar asked Nov 11 '22 04:11

J.T.


1 Answers

This is not an answer to your "why?" but a different "why?".

Why do you care? In a real-world sort of way, I mean. Enough to ask on StackOverflow.

I think it's a great question (and the sort of stuff that fascinates me), but I blog about this sort of thing, and it's my hobby.

However from a work-a-day point of view, before I started concerning myself with any of this sort of stuff, I'd be assessing how big the performance difference is? If, for argument's sake, you needed to loop over your code 1000000 times to amplify it enough to see meaningful results that using the request scope was twice as slow (at 2000ms, say) than using a passed-in reference (1000ms), it's not the 100% difference that's important; it's the fact that the difference is only 0.001ms per iteration: ie, it simply doesn't matter.

I make a point of posting this answer not necessarily for you, but for people who come later: be cautious of micro- / premature-optimisation. This sort of thing will be very unlikely to be the cause of anything you actually need to optimise.

In the meantime... have you run your tests on Railo to see if there's any differences?

It'd be cool if you could blog all your findings!

like image 104
Adam Cameron Avatar answered Nov 15 '22 13:11

Adam Cameron