4

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

Leigh
  • 28,765
  • 10
  • 55
  • 103
Magic Lasso
  • 1,504
  • 5
  • 22
  • 29

3 Answers3

8

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#">
Matt Busche
  • 14,216
  • 5
  • 36
  • 61
  • 1
    everyone says avoid isdefined, and it is a legacy function, but seriously who is going to notice an extra millisecond or 2.time would be better spent tuning poor queries, which usually saves seconds not milliseconds. – snake May 23 '13 at 08:08
  • 2
    IsDefined forces you to scope your variables, that's the reason to use it – Matt Busche May 23 '13 at 11:55
  • 1
    @MattBusche - I think you meant `structKeyExists` forces you to scope, right? – Leigh May 23 '13 at 16:24
  • @Leigh ha, yes. it was too early this morning. – Matt Busche May 23 '13 at 17:02
  • 1
    @snake `structKeyExists` forces you to scope your variables, that's the reason to use it – Matt Busche May 23 '13 at 17:03
  • Matt, yes i know that, I was referring to the "performance" reason that everyone gives for not using it. Obviously there are a lot of legacy apps out there still using IsDefined(), and so many many adevs are anal about this and say "you must spend lots of time and change all the code to use StructKeyExists" simply to save a few measly cycles. – snake May 23 '13 at 20:45
6

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().

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
5

In normal coding, there is no perceptible performance advantage between using one or another.

That being said, you should use structKeyExists() instead of isDefined() for one simple reason.

The structKeyExists() function forces you to scope your variables. The IsDefined() function allows for super sloppy code, which leads to inferior applications.

ColdFusion: More efficient structKeyExists() instead of isDefined()

Community
  • 1
  • 1
Evik James
  • 10,335
  • 18
  • 71
  • 122