In addition to tuning JVM arguments and adjusting ColdFusion Administrator settings, you can apply coding best practices to achieve performance improvements.
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")>.
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>
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>
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>
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.
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.
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.
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>
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.
When using CFHTTP set ResolveUrl=yes only when needed.
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" >
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.
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")>