So earlier today a few peeps on Twitter pointed out that a particular project page was running very slowly. I tried to replicate this but wasn't able to consistently. Then - all of a sudden - I could - and I couldn't understand why. You see - the code in question was something I knew was slow and something that was a bit out of my control - the SVN interface. I couldn't speed that up so I had made use of Model-Glue caching. This is a nifty little feature that probably doesn't get a lot of use out there (or maybe it does, let me know!) and allows for quick caching within your controller layer. However, I missed one very critical part of the docs:
Model-Glue 3's caching systems will, by default, cache elements for five seconds.
Yeah, seconds. Duh. So how did I find this? Using ColdFusion's simple, built in, debugging support. You know, the one you can turn on in one second and get reports on all your CFC/template execution times and database queries? I know I'm a fanboyevangelist and I'm supposed to push this stuff, but damn was that useful. Turned it on - ran my test - and within 5 minutes I had identified not only the sore spot but also about 5 database queries that I could cache. As an example, the list of project categories? I've added maybe 2 categories in the last year years. Why am I getting that darn list on each and every request?
<cffunction name="getProjectCategories" output="false" returnType="any">
<cfset var cats = cacheGet("riaforgeprojectcategories")>
<cfif isNull(cats)>
<cfset cats = variables.gateway.getall()>
<cfset cachePut("riaforgeprojectcategories", cats, createTimeSpan(7,0,0,0))>
</cfif>
<cfreturn cats>
</cffunction>
The open source license for a project? I fetched the details (just the name really) every time you viewed a project. I've edited licenses maybe 3 times in the history of RIAForge.
<cffunction name="getLicense" output="false" returnType="any">
<cfargument name="id" type="any" required="true">
<cfset var license = cacheGet("riaforgelicense_#arguments.id#")>
<cfif isNull(license)>
<cfset license = variables.dao.read(arguments.id)>
<cfset cachePut("riaforgelicense_#arguments.id#", license, createTimeSpan(7,0,0,0))>
</cfif>
<cfreturn license>
</cffunction>
<cffunction name="getLicenses" output="false" returnType="any">
<cfset var licenses = cacheGet("riaforgelicenses")>
<cfif isNull(licenses)>
<cfset licenses = variables.gateway.getAll()>
<cfset cachePut("riaforgelicenses", licenses, createTimeSpan(7,0,0,0))>
</cfif>
<cfreturn licenses>
</cffunction>
I did this a few times (to be honest, I could hack away at RIAForge even more, it's old and is probably due for a rewrite) and cut down the number of database queries per request in half. All by just enabling debugging and looking over the report.
Archived Comments
The project pages are very responsive now. Good work.
Thanks. I could tweak it even more - but that would involve - you know - actual work.
Worth remembering too that the debug template is editable, and can be reprogrammed/augmented to provide the information in a more useful way.
One thing I like to do is summarize my query times for the whole page in a simple bar chart, that shows how all the queries look relative to one another. In fact I posted a quick post about exactly this a few days ago http://www.bluemini.com/?la...
Damn good example Nick. The debug template being editable (and you being allowed to write your own) is what allowed ColdFire to be built.