How CFThread Can Help OR Hurt Performance
By Pete Freitag
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:
Test | Avg 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.
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:
- CFThread - Don't Abuse It
- OutOfMemoryError - GC overhead limit exceeded
- Cache Template in Request Setting Explained
- ColdFusion 9 Performance Brief from Adobe
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 may update the post with a better example.
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.
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.
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.