Mark Drew (Redux)- cf_etc...

a compendium of railo, cfml, cfeclipse and technology topics

Mark Drew (Redux)- cf_etc...

Generic Beans: Coldfusion VS Java

November 29, 2006 ·

In my previous tests I wanted to see how fast I could get the creation of components. I decided to re-write a Generic Bean in Java and see if the speed changed at all. I had done this with a defined bean (a Person with a name and an age), but what about a Generic Bean? I created the generic bean very quickly in Java, it hasnt got any logic in it, you create it and then put() and get() values or objects you have placed into this bean. There is no error checking, it could barf and do some crazy things so it's not production code, just for testing you understand. The code for the test is as follows, its pretty similar to my previous tests so nothing should shock you here: <cffile action="append" file="#expandPath("results/#FORM.testname#.txt")#" output="Instances,CFMLBean,JavaBean">
   <cfset testgroup = GetTickCount()>
   <cfloop from="0" to="2000" step="50" index="x">

      <cfset cArray = ArrayNew(1)>

      <cfset cStart = GetTickCount()>
      <cfloop from="1" to="#x#" index="c">
         <cfset cfGenBean = CreateObject("component", "GenericBean")>
         <cfset cfGenBean.put("name", "Bob" & c)>
         <cfset cfGenBean.put("age", c)>
         <cfset ArrayAppend(cArray, cfGenBean)>
      </cfloop>
      <cfset cTime = GetTickCount() - cStart>


      <cfset jArray = ArrayNew(1)>
      <cfset jStart = GetTickCount()>
      <cfloop from="1" to="#x#" index="j">
         <cfset jGenBean = CreateObject("java", "uk.co.markdrew.java.GenericBean")>
         <cfset jGenBean.put("name", "Bob")>
         <cfset jGenBean.put("age", j)>
         <cfset ArrayAppend(jArray, jGenBean)>
      </cfloop>
      <cfset jTime = GetTickCount() - jStart>
      <cffile action="append" file="#expandPath("results/#FORM.testname#.txt")#" output="#x#,#cTime#,#jTime#">
      |&amp;nbsp;
      <cfflush>
   </cfloop>
My CFFML based Generic bean is also pretty simple: <cfcomponent output="false">
      <cfset variables.values = StructNew()>

      <cffunction name="put" output="false" access="public" returntype="void">
         <cfargument name="key">
         <cfargument name="value">

         <cfset StructInsert(variables.values, arguments.key, arguments.value)>
      </cffunction>

      <cffunction name="get" output="false" access="public" returntype="any">
         <cfargument name="key">
         <cfreturn variables.values[arguments.key]>
      </cffunction>
   </cfcomponent>
The Java one is again, pretty much the same as above, but in Java: package uk.co.markdrew.java;
   import java.util.HashMap;
   public class GenericBean {
      private HashMap objectMap;
      public GenericBean() {
         super();
         this.objectMap = new HashMap();
      }
      public void put(String key, Object object){
         this.objectMap.put(key, object);
      }
      public Object get(String key){
         return this.objectMap.get(key);
      }
   }
So, what happened in this test? Well, from the chart you can see that Java won hands down! Maybe something to think about if you are doing a lot of object instantiations? Again, this is another Caveat emptor considering I might be wrong and delusional

Tags: coldfusion

7 responses

  • 1 Mike Brunt // Sep 22, 2008 at 4:11 PM

    Mark, I have been following this thread and it is thought provoking. I have been on site troubleshooting a large mach-ii application and noticed the immernse amount of Garbage Collection going on in in comparison to othe large CF Apps. Of course mach-ii is a CFC based framework. Do you have any thoughts on this- CFC based frameworks that is?
  • 2 Ben Nadel // Sep 22, 2008 at 4:11 PM

    Mark, Cool stuff. I don't want to mislead here, but I was at a CFUG meeting one time and this guy was talking about Java Beans and stuff (90% of which I didn't understand), but he demonstrated something along the lines that it was faster to create a Java bean on one server, serialize it, send it over the network to a JBoss (or something, again I dont know what I am talking about), de-serialize it, process it, reserialize, send back over the network and use THAN it was to the equivalent work in a local CFC.

    I am sure I am not explaining this accurately, but it was something pretty crazy like that.
  • 3 Andy Jarrett // Sep 22, 2008 at 4:11 PM

    Mark, you never said what platform you ran this on. Though I'm guessing, Mac and CFMX 7.02. It would be cool to see how BD and Railo stack up. I would do it myself, but im having issues with getting BD going (it's a cop-out i know :o) )
  • 4 Mark Drew // Sep 22, 2008 at 4:11 PM

    @Mike: I dont know about MachII but most frameworks have a number of CFC's that you then cache in some way so I the performance boost of putting trusted cache on might be very beneficial in that instance

    @Ben: What you are saying makes sense, Java by itself is DESIGNED to create objects, so serialising an object, doing stuff to it and then returning it is in itself not a massive hit.

    @Andy: Yeah, it was CFMX 7.02 on my Mac, and I shall do some other tests with the different engines, but I in this post I wanted to highlight the difference in speeds between a CFC and Java on the platform that most people use, using the idea of a Generic bean (following Peter Bell's blog you see)
  • 5 Elliott Sprehn // Sep 22, 2008 at 4:13 PM

    As a note to anyone who comes across this and wonders why CF might be so slow compared to the &quot;same&quot; thing in Java, it's because they're really really not the same thing.

    A component instance in CF is a proxy to an entire page. In fact, components are really coldfusion.runtime.TempalateProxy objects that extend coldfusion.runtime.CFPage objects which are the foundation unit of a cfm file that contain the function definitions for the CF functions. Each of your compiled cfm files extends this class.

    From this we can see that a cfc is just a proxy to an entire page, where the variables scope of that page has been exposed through the proxy so we can call methods on it. There's of course more magic to deal with the this and variables scopes, inheritance and the like, but that's the general idea.

    A &quot;simple bean&quot; in CF is an entire page, with it's own PageContext, metadata, output buffers. Each method is an entire class so we can pass method pointers around, something Java can't do, and there's lots of stuff in there to deal with the dynamic typing that Java wouldn't be dealing with, and more importantly could optimize the hell out of in the compiler because it knows the types in advance.

    CF8's improvements to cfcs should be interesting to research. If they're really still just page proxies than the entire CF runtime must be tons faster.
  • 6 Hem // Sep 22, 2008 at 4:13 PM

    Dear Mark,

    I'm kinda curious as to what performance difference would be for a compiled cf object.

    Here's the code you need to run in windows to do so.


    path=%path%;c:\cfusionMX7\bin\

    cfcompile.bat -deploy c:\inetpub\wwwRoot C:\Temp\uncompiled C:\Temp\compiled


    Thank you
  • 7 Mark Drew // Sep 22, 2008 at 4:13 PM

    I dont think the performance would change that much, apart from the initial hit as it would then be compiled and ready to go. YMMV though...