Recent Entries
- OT - Google Maps: In...
- Email Hijacked?
- CFUnited: Refactorin...
- CFUnited: Continuous...
- CFUnited: Prototypin...
- CFUnited: All about ...
- CFUnited: Event Driv...
- CFUnited: Integrated...
- CFUnited: ColdBox Fr...
- CFUnited: Design Pri...
Popular Entries
- SAML and ColdFusion ...
- Import/Export in SQL...
- SAML and ColdFusion ...
- SAML and ColdFusion ...
- SAML and ColdFusion ...
- CFUnited: All about ...
- Improving Performanc...
- Second Blog CFC Surv...
- SAML and ColdFusion ...
- SQL Server 2005 Expr...
Top Commenters
- Nathan Mische (12)
- CFdevfusion (6)
- CFFusionDev (5)
- Peter Bell (4)
- Sean Corfield (3)
- Rey Bango (3)
- Terrence Ryan (3)
- ah7866 (3)
- Scott (2)
- Jim Priest (2)
Slideshows
Pool Surprises...Sponsored Links
Search
Subscribe
Enter your email address to subscribe to this blog.RSS
Tags
cfug cfunited coldfusion flex generalArchives
- Adobe (5) [RSS]
- AIR (6) [RSS]
- ASP.NET (2) [RSS]
- BlazeDS (1) [RSS]
- Books (1) [RSS]
- CFEclipse (5) [RSS]
- CFML (0) [RSS]
- CFUG (26) [RSS]
- CFUnited (23) [RSS]
- ColdFusion (53) [RSS]
- College Football (3) [RSS]
- Conferences (1) [RSS]
- Development Tools (3) [RSS]
- DIY (1) [RSS]
- Eagles (3) [RSS]
- Fireworks (1) [RSS]
- Flash (3) [RSS]
- Flex (10) [RSS]
- Flyers (2) [RSS]
- Frameworks (5) [RSS]
- General (28) [RSS]
- Hockey (2) [RSS]
- Hosting (1) [RSS]
- House (2) [RSS]
- HTML (2) [RSS]
- JavaScript (1) [RSS]
- Jobs (1) [RSS]
- Macromedia (0) [RSS]
- Misc. (5) [RSS]
- Model-Glue (4) [RSS]
- Navy Football (5) [RSS]
- onair2007Philadelphia (3) [RSS]
- onairbustour (3) [RSS]
- Open Source (0) [RSS]
- Other (2) [RSS]
- Other Sports (4) [RSS]
- Performance (3) [RSS]
- Personal (2) [RSS]
- Phillies (2) [RSS]
- Projects, User Group Manager (1) [RSS]
- Rant (1) [RSS]
- Rants (1) [RSS]
- SAML (6) [RSS]
- Site (1) [RSS]
- Soccer (4) [RSS]
- SQL Server (2) [RSS]
- Transportation (1) [RSS]
- Wedding (2) [RSS]
AGGREGATORS
Improving Performance: Concatenating Large Strings
Posted On October 20, 2006 7:12 AM By Phil in ColdFusion,Performance
One of the more common programming tasks nowadays is to write audit log files, place large amounts of tracking within a database, or write large CSV files for export. The most common response when a question is asked on how to reduce the processing time of these transactions is to use the Java StringBuffer method. There is, however, a fairly straightforward method within ColdFusion itself that is just as efficient as using Java. This method is what I like to call the ArrayAppend/ArrayToList method. Let's look at a piece of code where a large CSV file is being created off of a very significatn report.
In the previous post in this series, I was referencing a User Group meeting/presentation/attendance list. I will continue to use the same example here. From the previous entry, the following query was being executed:
SELECT Mtg.meetingId, Mtg.Title AS Meeting, Mtg.Description AS MeetingDescription, Mtg.MeetingDate
Pres.presentationId, Pres.Title AS Presentation, Pres.Description AS PresentationDescription,
File.fileId, File.Filename, File.FileType,
Speak.FirstName AS SpeakerFirstName, Speak.LastName AS SpeakerLastName,
Attend.FirstName AS AttendeeFirstName, Attend.LastName AS AttendeeLastName
FROM Meeting Mtg INNER JOIN MeetingAttendees MtgAtt ON Mtg.MeetingId = MtgAtt.MeetingId
INNER JOIN Member Attend ON MtgAtt.MemberId = Attend.MemberId
OUTER JOIN Presentation Pres ON Mtg.MeetingId = Pres.MeetingId
OUTER JOIN File ON Pres.PresentationId = File.FileId
INNER JOIN Member Speak ON Pres.MemberId = Speak.MemberId
</CFQUERY>
<CFQUERY dbtype="query" name="qryMeetings">
SELECT MeetingId, Meeting, MeetingDescription, MeetingDate
PresentationId, Presentation, PresentationDescription,
fileId, Filename, FileType,
SpeakerFirstName, SpeakerLastName,
AttendeeFirstName, AttendeeLastName
FROM qryMeetings_base
ORDER BY MeetingDate, Presentation, Filename, AttendeeLastName, AttendeeFirstName
</CFQUERY>
< cflock name="CSVReport" timeout="20" type="exclusive" throwontimeout="true">
The main problem with this method is that there could be thousands of writes to the file. This is usually a first pass at solving this problem. Once this page comes to a crawl, the next phase is to usually try building one large string to use, replacing the CFLOCK and CFFILE tags in the previous example as follows:
<cfset CSVFileName="MeetingReport_#DateFormat(Now(),'mmddyyyy_hhnnss')#.csv">
<cfset strCSVReport = "" />
<table>
<tr>
<!-- Column Headings here -->
</tr>
<cfset strCSVReport = strCSVReport & qryMeetings.columnList >
</cflock>
<cfoutput query="qryMeetings">
<tr>
<!-- Data Element output items here -->
<cfset strCSVReport = strCSVReport & "#qryMeetings.Meeting#,#qryMeetings.Description#, ..." />
</tr>
</cfoutput>
</table>
<cflock name="CSVReport" timeout="20" type="exclusive" throwontimeout="true">
<cffile action="write" file="#GetTempDirectory#\#CSVFileName#" output="#strCSVReport#" >
</cflock>
This is closer to optimal as it has eliminated the many calls to write the file, however, it is eating up memory on each concatenation as ColdFusion creates a new variable instance each time a string is concatenated to itself. This is where we implement the ArrayAppend/ArrayToList methods, replacing the concatenation as follows:
<cfset CSVFileName="MeetingReport_#DateFormat(Now(),'mmddyyyy_hhnnss')#.csv">
<cfset arrCSVReport = ArrayNew(1) />
<table>
<tr>
<!-- Column Headings here -->
</tr>
<cfset ArrayAppend(arrCSVReport,qryMeetings.columnList) >
</cflock>
<cfoutput query="qryMeetings">
<tr>
<!-- Data Element output items here -->
<cfset ArrayAppend(arrCSVReport,"#qryMeetings.Meeting#,#qryMeetings.Description#, ...") />
</tr>
</cfoutput>
</table>
<cflock name="CSVReport" timeout="20" type="exclusive" throwontimeout="true">
<cffile action="write" file="#GetTempDirectory#\#CSVFileName#" output="#ArrayToList(arrCSVReport,'#Chr(10)#'#" >
</cflock>
We used this method in a number of our reports at work as well as in import/export logging and it reduced their processing time by almost 75%. I ran metrics, which I don't have access to anymore, where a report of 65,000 records processed the same using the ArrayAppend/ArrayToList method as it did using Java classes for the string building. Overall, if you are building large strings through concatenation, take a look at using this method, the processing savings are tremendous the large the data set gets.


philduba.com




Comments