Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsGeneralPHPASPPerlColdFusionFlashHTML, CSS, ScriptsBrowsers

Webmaster Forum / ColdFusion / Advanced Techniques / October 2007



Tip: Looking for answers? Try searching our database.

cfc generation is slow

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
obouillaud - 17 Oct 2007 16:26 GMT
Hi

Here is my problem :
as soon as I create a cfc, it takes a lot of time (on a computer time scale).

Here is a simple test :
On my server it takes between 170 and 200 ms for each loop of hundred cfc
generations.
That is around 16ms for each CFC... where is the error ???
As soon as I need inheritance or imbricated cfc's for example to display a
small list of 5 products on a page, it takes 150-400 ms to generate !!!

Do you have the same behavior ?

<cfloop from="1" to="10" index="j">
    <cfset start = GetTickCount()>
    <cfloop from="1" to="100" index="i">
        <cfset "product_#j#_#i#" =
CreateObject("component","composants.produits.test")>
    </cfloop>
    <cfset looptime = GetTickCount() - start>
   
    <cfoutput>
    #j# : #looptime# ms<br />
    </cfoutput>
</cfloop>

------------------------------------------------------
and my test.cfc  file :

<cfcomponent>  

</cfcomponent>
[CJ] - 17 Oct 2007 20:22 GMT
component instantiation has always been an expensive process, and not
well-suited for doing within a loop.

can't you instantiate it once, then do the assignment inside the loop?

<cfset myComponent = createObject('component', 'com.produits.test') />
<cfloop index="i" ... ><cfset "myVar#i#" = myComponent /></cfloop>

?
Adam Cameron - 17 Oct 2007 20:29 GMT
Which version of CF?

Signature

Adam

Grizzly9279 - 17 Oct 2007 21:26 GMT
This was a known issue with CF7 at least; rumor has it CF8 was supposed to
speed up object instantiation (among other things).  Your mileage may vary
though.

Like CJ suggested, you may need to re-design your approach to account for
performance limitations in this programming environment.

I've gone so far as to implement an "object recycling" mechanism in the past
so I could re-use old, discarded CFCs objects, since it was many times faster
to do that than to create brand new CFC instances every time.

Like anything, there's more than one way to skin a cat.  Sometimes you have to
get creative to get the desired result.  I know that's not the answer you were
looking for, but at least you know that you're not alone in this :)
obouillaud - 18 Oct 2007 08:42 GMT
[CJ] : your suggestion is very interresting, that's why I love forums, you can
pass 3 days looking for a solution and someone totaly outside of the project
finds a solution in a few minutes !

... too bad in the case I have the biggest problem, it's not possible as the
instancied object varies. I have a "product" abstract object which is
overridden by some "book", "software", ... objects. As I have betwen 10 and 20
different "flavours" of objects, even if I can instanciate them just one time
(which is better than on each row), I will still have 10 to 20 x 16ms per
page... which is still slow.

I'm working on a caching mechanism to store the objects in the Application
scope, it looks promising.
GArlington - 18 Oct 2007 10:03 GMT
>  [CJ] : your suggestion is very interresting, that's why I love forums, you can
> pass 3 days looking for a solution and someone totaly outside of the project
[quoted text clipped - 9 lines]
>  I'm working on a caching mechanism to store the objects in the Application
> scope, it looks promising.

You can cache the components in session scope (it is safer than
application scope), but depending on your component design you can
make them application global. I wrote an object caching component some
time ago, average request/response time is less than 1 ms. If you want
I can share that code and you can work on improving it.
Grizzly9279 - 18 Oct 2007 11:33 GMT
CF7 cannot create "copies" of CFCs unfortunately.   I can't speak for CF8
though.  CF8 was supposed to add support for object serialization however; this
leads to me believe that it should be possible in CF8 to "copy" an object, if
only by a serialization and de-serialization process.

So in other words, applying the assignment operator to a CFC will always
result in a pass-by-reference assignment (a pointer).  And no, the duplicate()
function does not work as you hope it would against CFCs :)

Best of luck.
cf_dev2 - 18 Oct 2007 16:27 GMT
> at the end I have a struct of objects which all refers to the same object,
with same properties.

Yes, its important to understand that CF passes most complex objects
(structures, queries, cfcs, ..) by reference.  You can use Duplicate() on some
objects to obtain an independent copy.  But as Grizzly9279 mentioned, cfc's are
not one of them
http://livedocs.adobe.com/coldfusion/7/htmldocs/00001008.htm
obouillaud - 18 Oct 2007 16:45 GMT
Ok... I didn't test but I'm quite sure that serialization + duplication +
"unserialiszation" is slower than a new CreateObject.

I tried my Application scope cache... and if it seems perfect on my dev
server, it seems a bad idea on my production server.
The structure in the Application scope rise from a few KB to 10 MB, 15 MB
everything seems fine... but after a while the server becomes very slow,
unresponsive... with average response time higher than 60 seconds... an I have
to restart the server.

Too bad that the caching solution seems worse than the "slow solution"
Adam Cameron - 18 Oct 2007 21:53 GMT
> Ok... I didn't test but I'm quite sure that serialization + duplication +
> "unserialiszation" is slower than a new CreateObject.

Eek, yes.

Did you ever answer my question as to which CF version, btw?

One thing you could look at is - and this is a bit of a cop-out, I agree -
is to store the member variables of the object in a cache (so that's just a
struct), and use the (cached) CFC instance as a factory sort of
arrangement.  When you need to do any operations on the object, pass the
cached struct in as one of the arguments of the method you're calling.  Not
very object-oriented, no, but CF ain't OO.  Plus it has trouble
instantiating objects, so one has to work around this.

Signature

Adam

obouillaud - 19 Oct 2007 08:33 GMT
Adam : in my first post is written "I'm running CF8 but it was the same thing
on CF7"...  That should answer your question :-)

Your suggestion makes me think that in fact it would probably be a better idea
to avoid CFC usage. Maybe just cfm pages with includes and functions should be
far more efficient !
Adam Cameron - 19 Oct 2007 10:43 GMT
> Adam : in my first post is written "I'm running CF8 but it was the same thing
> on CF7"...  That should answer your question :-)

Did you edit the post to include that after the fact?  I'm reading from the
NNTP feed, and that's not in your first post that I'm looking at.

Either way, sorry for the "silly" question.

I was hoping you were foing to say "CFMX6.0", or something, which was a
known dog at instantiating CFCs.  CF8's a lot better.

>  Your suggestion makes me think that in fact it would probably be a better idea
> to avoid CFC usage. Maybe just cfm pages with includes and functions should be
> far more efficient !

Yeah, they can be a bit of a pain in the butt performance-wise.  It depends
on the situation.  They're fine for stateless factory type things, or as
"bags o' functions", but not much chop as "real" objects, if one's app is
going to rely heavily on them.

One thing I think of when I'm looking at your code (which I realise is just
an example,but infer it's related to your real situation) though: you're
basically generating a collection of products in your loop.  So why don't
you create ONE collection class, which loads its data from [whatever
mechanism your individual products are loaded via].  I guess it depends on
whether you're dealing with the collection or with one-off products more
often.  The collection class could still have a getProduct(sku=something)
method.

Signature

Adam

GArlington - 19 Oct 2007 10:36 GMT
> Ok... I didn't test but I'm quite sure that serialization + duplication +
> "unserialiszation" is slower than a new CreateObject.
[quoted text clipped - 7 lines]
>
>  Too bad that the caching solution seems worse than the "slow solution"

Your problem may be to do with live server (mis) configuration.
I just implemented object caching (currently about 5600 objects cached
at 50KB each) AND component caching on per session basis (average 400
concurrent sessions with 20-30 cached components each). It runs on
live server with average page response time under 1 second.
obouillaud - 19 Oct 2007 15:25 GMT
I edited my first post a few minutes after its initial post... I can't remember
why, but I guess it was to add the CF8/CF7 fact... I didn't knew that the
newsgroup didn't reflect the changes of the posts. Sorry.

I already use a collection... but it's a collection of "product" objects... ;-(
Adam Cameron - 19 Oct 2007 15:53 GMT
>  I already use a collection... but it's a collection of "product" objects... ;-(

Sure: I'm imagining it's this collection you sample code came from, this
being the case.  Which would be fine if that notion worked.

What I'm suggesting is not make a "collection of objects"; make a class
that is "ObjectCollection", and don't deal with the individual items as
objects; deal with ONE object which works @ collection-level, not
object-level.

Signature

Adam

obouillaud - 20 Oct 2007 10:44 GMT
I understand. and I should store the properties of my products in a struct ?
And the methods within the ObjectCollection cfc ?

for example I have a "set_price(float price ,bool with_taxes)" method in my
product object. It set both the price with taxes and without taxes (that's an
example). So in your suggestion I should rewrite this method with something
like :
set_price(float price ,bool with_taxes, struct table_of_products,int
product_id) which means pass the struct of my products and the id of the
product I want to se the price ?
Adam Cameron - 22 Oct 2007 08:57 GMT
> I understand. and I should store the properties of my products in a struct ?
>  And the methods within the ObjectCollection cfc ?

Yep.

Note: this is only a suggestion, and something to mull over.  I've given it
as much thought as it has taken me to type in.

>  set_price(float price ,bool with_taxes, struct table_of_products,

Well the struct would be one of the member variables of the object, so
there's probably no reason to pass it in to the method.  It's "safe" to
reference member variables directly.

My suggestion of having an external struct holding the data was back when
we were discussing having the Product CFC instance as a "bag o' functions"
relating to a product struct - which would accordingly only need to be
created once, as opposed to a discrete object for each product.

If you're just having the one object for the ProductCollection, then the
data should remain in the object.

Signature

Adam

obouillaud - 24 Oct 2007 09:39 GMT
That's really lots of work, just to bypass Coldfusion flaws !
They said since CFMX  that it's an object oriented language. Everybody is
writing about inheritance, design patterns, ... and when you use it... you end
up with a slow application, which also seems the cause of server instabilities
(cpu/memory intensive) !

Sometimes I think about my firsts CF pages, with includes, and query + output
directly in the cfm file... not very good for reusability... but the
performances were never a problem !
Adam Cameron - 24 Oct 2007 14:42 GMT
> That's really lots of work, just to bypass Coldfusion flaws !

Sure.

>  They said since CFMX  that it's an object oriented language.

No-one that knows what they're talking about has ever claimed that.

It's got some object-oriented touches to it.  It ain't OO, and Macromedia /
Adobe have never claimed as much.

To be honest, we've had the problems you're seeing in the past, but not for
a couple of years.  And we use CFCs fairly extensively.  Sometimes stuff
needs coding around or to be factored in a different way, but as long as
one doesn't get too dogmatic about things, there's no probs with that.

Signature

Adam

rupesh_kumar - 30 Oct 2007 11:19 GMT
obouillaud,
CF8 is much faster than CF7 when it comes to cfc creation. Running your code,
my laptop (which is very slow) takes 100 ms for each of iteration. And since
you are creating 100 objects in each iteration, thats nearly 1 ms for each CFC
which is not that bad. Is it? On a better server machine this time will be much
smaller.
You can make it even faster by enabling trusted cache.

Regarding cfc, Duplicate does support cfc in CF8. And I think there is some
misconception regarding cfc serialization and duplicate. You do not need to
worry about serialization and deserialization. All you do is to call Duplicate.
But that time will be more or less same as cfc instantiation time.
obouillaud - 30 Oct 2007 12:52 GMT
you know what ? I made a miscalculation... 170 ms fo 100 iterations... thats
1.7 ms by iteration, not 17 ms !
That said, I think in fact thats file-system related as when I test on my
prouction servers (with files stored on an external NAS), a 100 iterations loop
takes between 700 and 1500 ms to complete...

As soon as I enable trusted cache the performances are awesome !!!
I will give trusted cache a try...
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.