Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Coldfusion: Is setting a default or using isdefined faster for arguments?

Tags:

coldfusion

Is it faster to test for existence isdefined("arguments.argument") or set a default value for arguments.argument?

like image 701
Magic Lasso Avatar asked Dec 01 '22 21:12

Magic Lasso


2 Answers

I ran a test using isDefined(), structKeyExists() and with a default value set. I came up with

isDefined - 184ms for 100k iterations
structKeyExists - 149 ms for 100k iterations
Default - 139ms for 100k iterations

So, looks like setting a default is the fastest option, but the difference between a default value and structKeyExists is so minimal, it doesn't matter. I would refrain from using isDefined() anywhere in your code.

The code I ran is below.

<cfset loops = 100000>
<cffunction name="myfunc" returntype="void">
    <cfargument name="myTest">
    <cfif isDefined('arguments.myTest')>

    </cfif>
</cffunction>

<cffunction name="myfunc2" returntype="void">
    <cfargument name="myTest">
    <cfif structKeyExists(arguments,'myTest')>

    </cfif>
</cffunction>


<cffunction name="myfunc3" returntype="void">
    <cfargument name="myTest" default="">
</cffunction>

<cfset start = getTickCount()>
<cfoutput>
    <cfloop from="1" to="#loops#" index="i">
        #myfunc()#
    </cfloop>
</cfoutput>
<cfdump var="#getTickCount() - start#"><br>

<cfset start = getTickCount()>
<cfoutput>
    <cfloop from="1" to="#loops#" index="i">
        #myfunc2()#
    </cfloop>
</cfoutput>
<cfdump var="#getTickCount() - start#"><br>

<cfset start = getTickCount()>
<cfoutput>
    <cfloop from="1" to="#loops#" index="i">
        #myfunc3()#
    </cfloop>
</cfoutput>
<cfdump var="#getTickCount() - start#">
like image 190
Matt Busche Avatar answered Dec 10 '22 05:12

Matt Busche


As @matt-busche indicated, worrying about the performance of this sort of thing is a case of premature optimisation: the performance differences are inconsequential. It probably took more time to type the question in than the cumulative time one or other would save you throughout the entire life of the application you're writing.

What you should be aiming for is writing clear code, that most accurately reflects the intent of the logic and the intended usage of the code.

You should set a default for your argument if that value for the default is the most likely useful value for that argument. This is not always appropriate: sometimes there's no "most likely useful value", so the argument should not have a default, and accordingly require the calling code to pass a value.

One should never write code that sets a default just so subsequent code doesn't break (eg: defaulting a string argument to "" just so one can safely assume it exists in subsequent code).

One benefit of specifying an argument default is that the default is reflected in the component's metadata, and its autogenerated docs. This is handy if you're writing an API for third-party consumption.

On the other hand one should generally avoid isDefined() as it's a pretty limited, inaccurate function, and I've seen it give false positives in some rare situations too (and it's not just me not understanding the scope-look-up rules).

Almost always one ought to use structKeyExists() over isDefined().

like image 24
Adam Cameron Avatar answered Dec 10 '22 03:12

Adam Cameron