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.