Accessibility

Table of Contents

Performance tuning for ColdFusion applications

Coding best practices for ColdFusion performance

In addition to tuning JVM arguments and adjusting ColdFusion Administrator settings, you can apply coding best practices to achieve performance improvements.

Fully scoped variables

You can improve performance by always qualifying your variables with the proper scope. Wherever possible use fully scoped variables. A variable that has a scope prefix will be evaluated quicker than an unscoped variable.

For example, <cfif isdefined("variables.foo")> is better from a performance perspective than <cfif isdefined("foo")>.

# evaluations:

Complex dynamically constructed expressions will negatively affect performance. For example:

<cfset #foo# = "#bar()#">

The code above should be replaced with the much simpler and more efficient:

<cfset foo = bar()>

IIf() and cfif-else

Always use cfif and cfelse instead of IIf(). The cfif construct is significantly faster and more readable.

evaluate()

To evaluate a dynamic variable, where possible use # instead of evaluate().

For example, avoid using:

<cfset value=evaluate("form.field#i#")>

Instead use:

<cfset value=form["field#i#"]>

compare() and compareNoCase()

Use compare() or compareNoCase() instead of the is not operator to compare two items. They are a bit faster.

For example, avoid using:

<cfif x is not "a">

Instead use:

<cfif compareNoCase(x, "a") neq 0>

listFindNoCase() and listFind()

Use listFindNoCase() or listFind() instead of the is and or operators to compare one item to multiple items. They are much faster.

For example, avoid using:

<cfif x is "a" or x is "b" or x is "c">

Instead use:

<cfif listFindNoCase("a,b,c", x) is not 0>

Query caching

Querying a database is one of the most time consuming parts of a ColdFusion page. ColdFusion provides query caching as a way to avoid repeatedly querying the database by caching the query recordset. Queries that do not change frequently are the best candidates for caching.

In ColdFusion Administrator you can specify the maximum number of queries that can be cached at a time. There is no limit on the size of a query, so if there are many queries with large recordsets in the cache then it may cause a memory overflow. As a good practice avoid caching queries for a long time.

The <cfquery> tag provides a cachedWithin attribute to specify the time period for which to cache a query. For example, the recordset for the following query will be cached for six minutes.

<cfquery name="GetParks" datasource="cfdocexamples" 
    cachedwithin="#CreateTimeSpan(0, 0, 6, 0)#">
    SELECT *     FROM Parks
</cfquery>

cfqueryparam

You can use cfqueryparam to optimize a query. Consider the following query:

SELECT * FROM    TABLE_NAME
WHERE  
COLUMN = #variable#

If this query is executed repeatedly with different values for variable then using an SQL bind variable will be faster. The cfqueryparam tag creates these bind variables:

SELECT * FROM   TABLE_NAME
WHERE
COLUMN = <cfqueryparam cfsqltype="query" value="#variable#">

This allows the optimizer to compile the query once and reuse it every time the query is executed. It is also more secure since it prevents malicious SQL from being passed into a query via a variable.

blockFactor

By default, the cfquery tag returns results sets from databases one record at a time. The blockFactor attribute tells ColdFusion server (which passes this information to the database driver) to retrieve between 1 and 100 records at a time. For queries that typically return result sets larger than a single row, requesting multiple rows in a block can result in a substantial performance gain. Setting this value too high can diminish performance as well, so it is recommended that you tune this number based on the expected average size of the result set.

Note: If you know that less than 100 rows will be returned (for example if you're writing a query that either returns 0 or 1 rows), do not bother adding the blockFactor attribute.

Caching

Use the <cfcache> tag in pages with contents that are not updated frequently. This tag tells ColdFusion server to cache the HTML to a temporary file. When ColdFusion gets a request for a cached ColdFusion page, it retrieves the pregenerated HTML page without having to process the ColdFusion page, thus improving performance.

For more information on this tag and its use, see Caching ColdFusion pages that change infrequently.

cfsavecontent

For ColdFusion pages that contain some dynamic information and some content that changes less frequently, the <cfcache> tag should not be used. Instead you can use <cfsavecontent> to cache infrequently changing output in a shared scope variable. There is a tradeoff, however, due to the overhead of locking a shared scope variable. For detailed information on this and examples see Caching parts of ColdFusion pages.

The <cfsavecontent> tag can also be used for concatenation, for which it is much faster than <cfset>. Here is an example using <cfset>:

 <cfset result = "">
     <cfloop from="1" to="100" step="1" index="i">
          <cfset result = result & i>
     </cfloop>

The code below using <cfsavecontent> is much better from a performance perspective:

<cfsavecontent variable="result">
     <cfloop from="1" to="100" step="1" index="i">
          <cfoutput>#i#</cfoutput>
     </cfloop>
</cfsavecontent>

Stored procedures and SQL queries

Wherever possible use stored procedures (via <cfstoredproc>) instead of SQL queries. This will enhance both security and performance. Once a stored procedure is compiled, SQL uses this compiled code, while inline SQL statements are executed as a new query every time.

CFHTTP

When using CFHTTP set ResolveUrl=yes only when needed.

Searching in categories

ColdFusion 8 provides the Verity search engine for searching in files and database queries. Search performance can be increased if files are indexed in categories and then searches are conducted within specific categories in a collection rather searching in the whole collection.

For example:

<cfsearch 
   name="qsearch1"
   collection="verity_cat_collection"
   category ="cat_1"
   criteria="Coldfusion"
>

CFThread

ColdFusion 8 introduces a new CFML-based tag that enables application developers to quickly and easily add powerful multithreading capabilities to server applications. The <CFThread> tag enables asynchronous processing in CFML, which harnesses the power of today's processors to vastly improve overall user response times where long-running tasks are made up of autonomous processing steps and processed synchronously. The maximum number of threads available for CFThread can be set from ColdFusion Administrator on the Server Settings > Request Tuning page. If your application has more concurrent CFThread requests than the number specified in the Maximum Number Of Threads Available For CFTHREAD setting, then increase this limit. The same guideline applies to the Maximum Number Of Running JRun Threads setting.

File functions

Use file functions(e.g FileCopy(), FileRead(),FileWrite()) in place of <cffile> tag for better performance. The performance gain increases as file size increases.

For example, avoid using:

<cffile action="write" file="c:\temp\myfile.txt" output="Some Text">

Instead use:

<cfset FileWrite("c:\temp\myfile.txt","Some Text")>