150 likes | 265 Views
Muahahaha !. I just bit a byte!. Why is my code so slow?. Caching & Performance. In ColdFusion. Presented By Denard Springle NVCFUG June 2011. Write OOP Applications
E N D
Muahahaha! I just bit a byte! Why is my code so slow? Caching & Performance In ColdFusion Presented By DenardSpringle NVCFUG June 2011
Write OOP Applications • OOP applications run faster and perform better than procedural coded applications. OOP application’s use of encapsulation allows only those functions which need to be fired to fire, and those that don’t… don’t. • Java, the underlying engine behind ColdFusion, is a true Object Oriented language. OO in ColdFusion has been developed to map as much as possible to the Java model that underlies the ColdFusion engine. This allows CF code to execute faster when written in an OO fashion.It also makes for happy developers, managers andcustomers. Programming For Speed O… O… Who?
Exit As Quickly As Possible • Logic in applications should always be written to exit as quickly as possible under all circumstances. • Programmers have a tendency to write logic that checks for error conditions passively (at the end) rather than actively (at the beginning). This is a time honored tradition and one that is continually perpetuated in coding books. Stop it! Always check for error conditions first and plan the fastest exit strategy for all code. The less code that has to execute, the faster your application will run. Programming For Speed Where’s the Exit?!
Limit Nested Loops • Nested loops are sometimes unavoidable, but they should be avoided whenever possible. • Nested looping is both a blessing and a curse to developers. On the one hand it offers much needed functionality to iterate over multiple sets of inter-related data points. On the other hand, it kills servers. There are often alternatives to nested loops that developers ignore (mapping your data into a struct, for example) and many developers simply abuse the ability to nest loops without realizing the implicationsfor the performance of the application. Programming For Speed I’m Loopy!
Know Your ColdFusion • ColdFusion offers a number of handy functions which should be avoided like the plague. • ColdFusion is great. It gives us things like inline if (IIF) which one would logically assume runs as quickly as an if-then-else, but that’s a poor assumption. There are a number of functions in ColdFusion that don’t operate on the premise many developers think they do (structFind(), <cfmodule>, incrementValue(), etc.). As such, avoiding the processor intensive functions for those that behave better is always a preferred choice (e.g. struct.key, <cfinclude>, a=a+1). Programming For Speed Uhh...
Test Execution Speed • The most often overlooked data point in testing is execution speed. • Testing your code for execution speed is key to understanding which functions take too long. Database queries, math intensive reporting and internet protocol requests are no brainers for taking a long time and are often suspect enough to improve application performance significantly. There are other, less obvious, suspects to consider however – locking shared scope variables, for example. Using GetTickCount() at the beginning and end of your functions will help you isolate problem areas and keep you from pulling out hair. Programming For Speed Faster! Faster!
Use Stored Procedures • Stored procedures take away much of the overhead involved with dealing with database queries. • Stored procedures take a tremendous load off of your ColdFusion server and place it squarely in the hands of your database server. Understand that this is literally a transfer of CPU and memory load from your application server to your database server. Stored procedures execute faster on most database servers than a query does from ColdFusion so it is typically a win/win situation. Programming For Speed I should store *this* guy!
Use Caching • Caching is a fancy way of saying – keep this just as it is and give it to anyone who asks for it. • For performance benefits, nothing beats caching. Caching of pages and queries, and indeed with ORM, allows you to provide quicker responsiveness for both static and dynamic* content. Pages and queries (e.g. ‘US States’ table in a DB) that never change should always be cached. ColdFusion doesn’t have to process the page or the query again until the cache expires, providing instant-on access to pages andcritical data (e.g. reporting). *dynamic content that changes infrequently Cashing In On Cache Cash?!
Page Caching • <cfcachetimespan="#CreateTimespan(1, 0, 0, 0)#" directory="e:/temp/page_cache“> • You tell ColdFusion to cache the page results by putting a cfcache tag on your ColdFusion page before code that outputs text. The tag lets you specify the following information: • Whether to cache the page results on the server, the client system, or both. The default is both. • The directory on the server in which to store the cached pages. • The time span that indicates how long the page lasts until it is automatically flushed. Cashing In On Cache Oh, *Cache*
Partial Page Caching • <cfsavecontentvariable=“SESSION.myVar”></cfsavecontent> • One handy but not very obvious way to use <cfsavecontent> is in the Application or Session scope of your application (typically in OnApplicationStart and/or OnSessionStart). By saving infrequently changing but frequently presented complex data in this way you can significantly decrease individual page load times. Because of the overhead of locking shared scope variables, use this technique only if the processing overhead of generating the output is more than theprocessing overhead of locking the shared scope. Cashing In On Cache
Query Caching • <cfquerydatasource=“myds" name=“qGetStates" cachedWithin="#CreateTimeSpan(0,1,0,0)#"> • The cfquery tag cachedWithin attribute tells ColdFusion to save the results of a database query for a specific period of time. This way, ColdFusion accesses the database on the first page request, and does not query the database on further requests until the specified time expires. Using the cachedWithin attribute can significantly limit the overhead of accessing databases that do not change rapidly. This technique is useful if the database contents only change at specific, known times, or the query does not require up-to-date results.(e.g. Google Adwordsreports are delayed 1 hr.) Cashing In On Cache Day, Hour, Minute, Second!
Flushing The Page Cache • <cfcacheaction=“flush” [directory="e:/temp/page_cache“]> • You can use the cfcache tag with the action="flush" attribute to immediately flush one or more cached pages. You can optionally specify the directory that contains the cached pages to be flushed and a URL pattern that identifies the pages to flush. If you do not specify a URL pattern, all pages in the directory are flushed. The URL pattern can include asterisk (*) wildcards to specify parts of the URL that can vary. If you have a ColdFusion function that updates data that you use in cached pages, that function should include a cfcache tag that flushes all pages that use the data. Cashing In On Cache FLUSH!
Flushing The Query Cache • <cfquerydatasource=“myds" name=“qGetStates" cachedWithin="#CreateTimeSpan(0,0,0,0)#"> • One of the first hurdles most developers face implementing query caching is how to undo the cache. Often in testing phases one discovers the database table didn’t have all the data it needed or needs a new field (or two) ‘manager special’ but one already has a cached query and doesn’t understand why they’re always getting the same results. I know it seems obvious, but it really isn’t when you first play with query caching ;)Setting your cachedWithintimespan to nothing (0,0,0,0)flushes the cached query and immediately calls thedatabase for your precious missing data! w00t! Cashing In On Cache That’s what she said!
ORM and Caching – Session and Secondary Level Caches • Cache data of a persistent object • <cfcomponent persistent="true" schema="APP" table="Artists" cachename="artist" cacheuse="read-only"> • Cache the association data of a persistent object • <cfpropertyname="art" fieldtype="one-to-many" cfc="CArt" fkcolumn="ArtID" cachename="ArtistArts" cacheuse="read-only"> • Cache query data • availableArts= ORMExecuteQuery("from CArt where issold=0", {}, false, {cacheable=true, cachename="availableArtsQuery"}); • See the Developing ColdFusion 9 Applications guide / ColdFusion ORM / Performance optimization / Cachingsection for full details of ORM caching techniques. Cashing In On ORM Cache Nom NomNom
ORM and Caching – Session and Secondary Level Caches • Optimizing ColdFusion Applications • There is no blog post for ColdFusion tags to avoid!! • Performance tuning ColdFusion servers Additional Resources We hope you enjoyed this! w00t!