Array Iteration Is Much Faster That Struct Iteration (Thanks Eric Stevens)

Posted May 27, 2008 at 8:32 AM by Ben Nadel

Tags: ColdFusion

Last week, I claimed that Struct iteration would be faster than array iteration in ColdFusion. This wasn't totally out of left field - what I have read about the two different objects and their underlying Java classes (FastHashTable and ArrayCollection) would have suggested that look ups on a Struct were faster than look ups on an array. After I made this claim, Eric Stevens of the B & E Blog did some performance testing and found that I was totally wrong. His test was quite thorough and clear, but it was so shocking that I had to see it for myself:

  • <!--- Create an array to populate. --->
  • <cfset arrData = [] />
  •  
  • <!--- Create a struct to populate. --->
  • <cfset objData = {} />
  •  
  •  
  • <!--- Now, populate both using 1-based index. --->
  • <cfloop
  • index="intIndex"
  • from="1"
  • to="100000"
  • step="1">
  •  
  • <!--- Add to array. --->
  • <cfset arrData[ intIndex ] = true />
  •  
  • <!--- Add to struct. --->
  • <cfset objData[ intIndex ] = true />
  •  
  • </cfloop>
  •  
  •  
  • <!--- Iterate over array. --->
  • <cftimer
  • type="outline"
  • label="Array Iteration">
  •  
  • <!--- Use index loop. --->
  • <cfloop
  • index="intIndex"
  • from="1"
  • to="#ArrayLen( arrData )#"
  • step="1">
  •  
  • <!--- Loop up value using Array index. --->
  • <cfset blnValue = arrData[ intIndex ] />
  •  
  • </cfloop>
  •  
  • Done.
  •  
  • </cftimer>
  •  
  •  
  • <!--- Iterate over struct. --->
  • <cftimer
  • type="outline"
  • label="Struct Iteration">
  •  
  • <!--- Use index loop. --->
  • <cfloop
  • index="intIndex"
  • from="1"
  • to="#StructCount( objData )#"
  • step="1">
  •  
  • <!--- Loop up value using struct key. --->
  • <cfset blnValue = objData[ intIndex ] />
  •  
  • </cfloop>
  •  
  • Done.
  •  
  • </cftimer>

Just as with Eric's findings, I found that the Array iteration was about 2-3 times faster than the Struct iteration, even when we were iterating over explicit keys (ie. not doing a Collection loop). Even after seeing this, something about it feels hard to believe. This is some good information to know.

What was also very interesting to see was that the List loop was almost as fast as an Array loop (one that uses the List attribute of the CFLoop, not one that uses ListGetAt()). This is something that I never really thought about before; I had just assumed everything with lists was slower than non-lists, but I guess ColdFusion is really being smart about it. Whether it is converting it to an array behind the scenes, or keeping track of the offset (as Eric theorizes), it is good to see that it is so fast.



Reader Comments

May 27, 2008 at 9:32 AM // reply »
92 Comments

Missed you at WebManiacs Ben. It was a pretty good time.


May 27, 2008 at 9:36 AM // reply »
10,640 Comments

@Andy,

Sorry man. I heard it was a lot of fun. Hopefully one day I will get down there. Going to CFUnited soon, at least.


May 27, 2008 at 9:42 AM // reply »
15 Comments

That's good to know about lists not being slow after all. I like using lists if all I need is a shallow 1D string of data. CF has lots of list functions and because of that it's more flexible than using a 1D array. A few times I've used 2 or 3 lists to create pseudo 2D or 3D arrays just so I can use the list functions, but if any of the lists get out of synch with each other (e.g. become different lengths) then it's as good as dead.

But CF8 and 8.01 introduced faster ways to create arrays which had previously been one of the grievances I had with using arrays in CF.


May 27, 2008 at 9:54 AM // reply »
10,640 Comments

@Gary,

For small sets of data, there is really no difference. The research above is really all theoretical and would really only come into use on extremely high traffic sites or algorithms that work with a tremendous amount of data.

For your average stuff, lists are just fine.


May 27, 2008 at 11:27 AM // reply »
18 Comments

I've always been impressed by the speed and variety of list functions. Another intangible to consider is the fact that list looping is SO EASY to construct and understand. They all have their place, but I'm glad that we don't have to shy away from this one.


May 27, 2008 at 12:07 PM // reply »
10,640 Comments

@Dan,

True. And remember that we are talking about minor optimizations. Certainly, you are never going to have a system where List looping and manipulation is your bottleneck :)


May 27, 2008 at 3:56 PM // reply »
32 Comments

I've always detested lists. I'm highly allergic to the idea that they can be broken by inserting data that contains a delimiter character, and the ListAppend function won't complain. They're not bad when dealing with, for example, a list of only numbers, and they're not too bad for dealing with really small sets of data which you control completely. But as soon as you take user input and pass it through a list, you're playing with fire.

It should be noted that ListGetAt(), ListFind(), and most other such functions are really terrible performers in general unless dealing with very small sets of data. <cfloop list> performs quite respectably because it never really has to search the list.

Even though <cfloop collection> under-performs compared to <cfloop list>, structs are a much more natural fit for managing the sort of complex data we'll encounter day-to-day. I almost always use a struct or an array for juggling data in my scripts.


Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »