ColdFusion 8 ValueObjects vs Typed Structs for Flex RemoteObjects

March 28, 2008

ColdFusion Objects transfer nicely over to Flex, making the remote data connection for Flex run like a dream.  It can get out of hand, however, when there are a large number of Objects to return from ColdFusion, for example, an array of ValueObjects, which might have other value objects as members.  In researching this, I ran across a few very helpful postings.  Basically, CF8 has a workaround wherein you use typed Structs instead of full blown Objects to pass VO’s to Flex:

http://www.briankotek.com/blog/index.cfm/2008/1/28/Returning-Typed-Structs-vs-CFCs-to-Flex

http://groups.google.com/group/transfer-dev/browse_thread/thread/0abdb2191dcfd226#2cbf827754e75376


So, I decided to run a few very simple tests to see what the impact of CreateObject was on a large dataset.  I put together a CF script with a loop to create 5000 objects using CreateObject (with init), another for 5000 with CreateObject (without init), another to simply duplicate a template Object and another to create 5000 structs.  The breakdown and the code follow:
 

Test

Iterations Elapsed Time (ms) ms/Instance
structTest 5000 157 0.0314
FullCreateTest 5000 17468 3.4936
createTest 5000 16610 3.322
dupeTest 5000 12469 2.4938
structTest 5000 15 0.003


This was run on a CF8 Box with JRun running on Java 1.5 I had similar results on a CFMX 7 Box with JRun running on Java 1.42 The option of rolling query results into typed structs is really a lifesaver given the performance numbers.       

<cfset t1 = GetTickCount() />

<cfset myArray=ArrayNew(1)>
<cfloop from=”1″ to=”5000″ index=”i”>
<cfset newStruct=StructNew()>
<cfset newStruct[“iter”] = #i# />
<cfset ArrayAppend(myArray,newStruct) />
</cfloop>
<cfset t2 = GetTickCount() />
<cfset elapse1 = t2 – t1 />
<cfset myArray2=ArrayNew(1)>

<cfloop from=”1″ to=”5000″ index=”i”>
<cfset newObj=CreateObject(“component”,”com.test.TestIter”) />
<cfset newObj[“iter”] = #i# />
<cfset ArrayAppend(myArray2,newObj) />
</cfloop>
<cfset t3 = GetTickCount() />
<cfset elapse2 = t3 – t2 />
<cfset myArray3=ArrayNew(1)>

<cfloop from=”1″ to=”5000″ index=”i”>
<cfset newObj2=CreateObject(“component”,”com.test.TestIter”).init() />
<cfset newObj2[“iter”] = #i# />
<cfset ArrayAppend(myArray3,newObj2) />
</cfloop>
<cfset t4 = GetTickCount() />
<cfset elapse3 = t4 – t3 />
<cfoutput>Results<br/>Structs : #elapse1# ms for 5000</br>

CreateObject (no init) #elapse2# ms for 5000<br/>CreateObject (with init) #elapse3# ms for 5000<br/></cfoutput>

<cfcomponent name="TestIter"> 
      <cfproperty name="iter" type="numeric"> 
      <cffunction name="init"> 
            <cfreturn this /> 
      </cffunction> 
</cfcomponent>