Pete Freitag Pete Freitag

How CFThread Can Help OR Hurt Performance

Published on July 09, 2009
By Pete Freitag
coldfusion

I am working on a performance analysis for a client, some page requests need to do a cfhttp call, I had the thought to use cfthread for the http call, so that other processing could happen in parallel.

Curious about this, I wrote some simple scripts to test, first my control script:

<cfhttp url="http://google.com/robots.txt" method="get"></cfhttp>
<cfdbinfo datasource="cfdocexamples" name="tables" type="tables">
<cfoutput query="tables">
    <cfif Left(tables.table_name, 3) IS NOT "SYS">
        <cfquery datasource="cfdocexamples">
            SELECT * FROM #tables.table_name#
        </cfquery>
    </cfif>
</cfoutput>

Next my threaded script:

<cfthread name="doit">
  <cfhttp url="http://google.com/robots.txt" method="get"></cfhttp>
</cfthread>
<cfdbinfo datasource="cfdocexamples" name="tables" type="tables">
<cfoutput query="tables">
    <cfif Left(tables.table_name, 3) IS NOT "SYS">
        <cfquery datasource="cfdocexamples">
            SELECT * FROM #tables.table_name#
        </cfquery>
    </cfif>
</cfoutput>
<!--- make sure thread is done processing --->
<cfthread action="join" name="doit" />

I then used Apache Bench to create some concurrent load on the scripts:

TestAvg Execution Time
Control (10 concurrent requests)143ms
Control (15 concurrent requests)221ms
Control (20 concurrent requests)290ms
Threaded (maxthreads=10, 10 concurrent requests)119ms
Threaded (maxthreads=5, 10 concurrent requests)247ms
Threaded (maxthreads=2, 10 concurrent requests)727ms
Threaded (maxthreads=10, 15 concurrent requests)195ms
Threaded (maxthreads=10, 20 concurrent requests)248ms

As you can see when you limit the number of threads that can be created you create a bottle neck in your application (this is why I wrote an entry when CF8 came out titled CFThread Don't Abuse It. You might wonder why I choose maxthreads=2 for one of the tests... If you are running Standard Edition that is the most concurrent threads you are allowed to create with cfthread, for a situation like this it can really hamper performance.

This test also illustrates how using threads (with the correct settings) can increase performance.



cfthread performance coldfusion cfhttp

How CFThread Can Help OR Hurt Performance was first published on July 09, 2009.

If you like reading about cfthread, performance, coldfusion, or cfhttp then you might also like:

FuseGuard Web App Firewall for ColdFusion

The FuseGuard Web Application Firewall for ColdFusion & CFML is a high performance, customizable engine that blocks various attacks against your ColdFusion applications.

CFBreak
The weekly newsletter for the CFML Community


Comments

I'd be curious what your results would be if you replaced the CFHTTP altogether with the sleep() method call. Basically, so the first example is *just* a sleep() call and the second example has the sleep call wrapped in the cfthread.

This might give you a more accurate simulation. My only concern would be that the sleep() tag is somehow preventing the threads from being activated since they are queued.
by Ben Nadel on 07/09/2009 at 3:33:33 PM UTC
@Ben - actually using sleep() for this test was probably a bad choice on my part. The reason is that the threaded cfhttp can execute without interruption while sleep() is going on, it lets other threads do their work.

I may update the post with a better example.
by Pete Freitag on 07/10/2009 at 7:54:48 AM UTC
Ah, ok. Looking forward to seeing what you come up with.
by Ben Nadel on 07/10/2009 at 9:21:53 AM UTC
I've updated the code, and the results to do DB calls instead of sleep() calls. The results are similar but less dramatic.
by Pete Freitag on 07/10/2009 at 10:05:13 AM UTC
Good update. This time, it took even longer, if I recall correctly. So, I guess one of the main points to take away is that threads are shared in the install, so you might have several apps / page requests all sharing the same queue, correct? As such, threading might be best used only when you don't care about the re-join of the main thread.
by Ben Nadel on 07/10/2009 at 11:50:41 AM UTC
@Ben, yes it did take longer, but I also had apache bench make 200 requests, instead of 100 per test as I did last time.

Yes the thread pool that cfthread uses is shared by all applications on the server, and is limited by the number specified in CF Administrator, or to 2 on standard.

Yeah a great use for threading is when you don't have to rejoin the main thread, in that case it should just get queued if there are not any available worker threads (I haven't tested that though). Another good case for threading is when you have a bunch of things to do, that could be done in parallel, I think HTTP calls, and DB calls are good examples of this, because there is some wait time while the external resource is doing its processing.

All this also depends heavily on how many processors you have at your disposal as well. The more processors the more potential benefit from threading.
by Pete Freitag on 07/10/2009 at 12:09:56 PM UTC
We have CF8 Standard in production and CFAdmin reports that 10 threads are the max, not 2 (I realize that the Adobe Standard vs Enterprise pdf lists 2). I've been using CFTHREAD heavily while developing web spiders and can confirm you can get more than 2 out of it. Server monitor should prove that if you're curious.

I concur that CFTHREAD works optimally for tasks that don't require a join. The trick is to re-think your application's design so that it can fit the multi-threaded paradigm. For my spiders, it often involves implementing a queue.
by Shawn Holmes on 07/10/2009 at 2:17:33 PM UTC