Since the day we started thinking about ColdFusion ORM, people have been raising concerns over it because of the CFC performance. We have heard people saying that ORM will be unusable because of poor CFC performance and it is a stupid idea to implement CFC based ORM. And today I heard Hal Helms and Brian kotek talking about it where Hal says that he shudders at the thought of hibernate integration in CF because of poor performance.
It is true that CFC performance is poor as compared to POJO and it will always be. ColdFusion CFC has lot of cost involved because of the dyanmic nature of it and additionally, it has reflection cost involved. I had shared some of the reasons with few of the community members and I thought it will be interesting to share it with a wider audience. Here are the main reasons :
- Unlike java where the class has a fully qualified name and is loaded only once in the classloader, when you create CFC, CF needs to search for the CFC file on the disk, compute the class name for it and then load it. And that happens on each object creation unless you have switched on trusted cache .
- CFC is compiled at runtime, loaded and constructed using reflection. I am sure you will be aware that reflection is much slower (25 times easily) than direct invocation in java.
- CFC has two different scopes – this and variables scope which is a struct. So every object creation involves two additional struct creation cost.
- CFC creation also involves running the default constructor i.e any code outside cffunction and that happens for each object creation. That involves the complete setup for method invocation i.e setting up localscope, superscope etc (another two structs here), which is also significant
- CFC allows UDFs to be added/removed from the object at runtime and hence methods are added to each object on object creation and that too in both the scopes (adding each UDFs in both the scopes also has significant cost). Thats the reason why object creation becomes costlier as you add methods in the CFC. Higher the number of methods, higher the object creation cost.
We have done a lot of performance improvements regarding CFC creation and invocation in ColdFusion 9 which I hope you would have noticed. But even then it can not match POJO performance and thats an unrealistic target.
So given that, lets come to the question – How much does CFC creation performance matters when it comes to ORM. In reality, not much. We have done a number of performance comparison between CFC and POJO with hibernate keeping everything else absolutely same. And all the time, CFC performance was same or better than POJO persistence. It might sound unbelievable and in fact I also could not believe it myself when I saw the performance numbers first. But that is the truth. And here is why it happens – When it comes to persistence, the time taken in DB operation and the persistence layer is much more than the time taken in object creation. And that cost is same for POJO and CFC. So the only difference in cost between CFC and POJO with respect to ORM is object creation cost and cost of populating/fetching the properties data. For instantiating POJO object and for using properties accessors, Hibernate has to use reflection which is always costly and that removes this cost difference of CFC and POJO. And for few of the runs, CFC was able to beat POJO as well and explanation for that is the optimizations that we have done in using accessors for properties.
I would be curious to know about your experience regarding CF-ORM performance and CFC performance in general. How has your experience been so far regarding CF-ORM peformance?