Published:
Warning: This blog entry was written two or more years ago. Therefore, it may contain broken links, out-dated or misleading content, or information that is just plain wrong. Please read on with caution.
Recently I had cause to look at speeding up a part of a new application which was creating an array of cfc objects using D/I1 and then populating them from a query. I noted that the time to call getBean() to get a new copy of each cfc was aprox 0.2 seconds which is not terrible except when you are doing it 66 times resulting in a load time of aprox 13 seconds before the beans are even populated with data.
The solution I came up with was to use DI/1 to get a single instance of the bean, then in a loop copy the original and populate the copy. This sped of the load time significantly, however I shortly discovered that the app was consuming a huge amount of memory and eventually would crash.
The problem turned out to be that in my end of years fatigue I had used the "duplicate()" function in my code.
duplicate() deep copies!
After going back and looking at the documentation again I did a facepalm when I read that the function does a deep copy of the object passed to it.
What that means for those of you who don't know is that every object referenced by that object gets duplicated recursively. Since the object I was duplicating was referencing multiple other singleton objects and each in turn were referencing other singleton objects and eventually the main framework object I was duplicating the entire application multiple times in memory "ouch!".
Solution
The solution of course was to use structCopy() instead, which despite its name also copies cfc objects only with structcopy it preserves references instead of duplicating the referenced object.
Testing
To demonstrate this I threw together this small test code. All we are doing here is create an instance of a counter component and then passing a reference into another component "main" which we then copy using both duplicate() and structCopy() methods.
I then call the original counter objects increment value and compare the before and after values of the counter when referenced through the different copies on the main component object.
Index.cfm
<cfset counter = createObject("component","counter").init()>
<cfset main = createObject("component","main").init(counter)>
<cfset maincopy = structCopy(main)>
<cfset mainduplicated = duplicate(main)>
<cfoutput>
<h2>Counter Values Before Increment</h2>
Original counter object: #counter.getCount()#<br/>
Counter object referenced from main object: #main.getCounter().getCount()#<br/>
Counter object referenced from copied main object: #maincopy.getCounter().getCount()#<br/>
Counter object referenced from duplicated main object: #mainduplicated.getCounter().getCount()#
<cfset counter.increment()>
<h2>Counter Values After Increment</h2>
Original counter object: #counter.getCount()#<br/>
Counter object referenced from main object: #main.getCounter().getCount()#<br/>
Counter object referenced from copied main object: #maincopy.getCounter().getCount()#<br/>
Counter object referenced from duplicated main object: #mainduplicated.getCounter().getCount()#
</cfoutput>
Main.cfc
component {
variables.counter = "";
public any function init(counter){
variables.counter = arguments.counter;
return this;
}
public function getCounter(){
return variables.counter;
}
}
Counter.cfc
component {
variables.counter = 0;
public any function init(){
return this;
}
public void function increment(){
variables.counter += 1;
}
public numeric function getCount(){
return variables.counter;
}
}
Result
As you can see from the below output the counter value when referenced from the duplicated main component does not match the others demonstrating that the counter object it references is not the same one referenced everywhere else now.
Original counter object: 0
Counter object referenced from main object: 0
Counter object referenced from copied main object: 0
Counter object referenced from duplicated main object: 0
Counter Values After Increment
Original counter object: 1
Counter object referenced from main object: 1
Counter object referenced from copied main object: 1
Counter object referenced from duplicated main object: 0
Archives Blog Listing
- 2023
- 2022
- 2021
- 2020
- September
- August
- June
- May
- April
- March
- 2019
- 2017
- 2016
- 2015
- June
- May
- April
- March
- January
- 2014
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- 2013
- December
- Configuring MariaDB on Slackware 14.1
- Feature idea for ColdFusion
- Changing the keyboard layout in KDE
- Charting and captcha tags do not work on new ColdFusion 10 install
- Slackware 14 NetworkManager
- Quickly empty ColdFusion's undelivered mail queue
- Update slackware packages with Slackpkg
- Matt Damon - Obedience
- Going back to linux
- November
- October
- June
- May
- April
- March
- February
- January
- December
- 2012
- December
- November
- October
- September
- Walmart - How We All Pay For Low Prices
- Calculate Week Numbers From A Base Day
- Who The Hell Is Electing These People?
- Find The Date Of The First Instance Of A Weekday In A Month
- Testing Email Without Spamming Your Customers
- Who Is Really In Charge?
- Shortening A Url And Getting A QR Code With Bit.ly
- Identifying Old Blog Entries
- August
- Reading A Remote File With CFHTTP Using Railo And ColdFusion
- Site Update Aug 2012
- Cynicism vs The Irish Spirit
- Calculating The Weeks Of A Month With ColdFusion
- Are We Being Chemically Dumbed Down?
- Subversion Per Repository Access Control
- Crash Course In MVC With FW1
- Debt Bomb, Debt Bomb, You're A Debt Bomb
- July
- Ditching Google - Blocking Tracking With The Hosts File
- Naomi Klein - The Shock Doctrine 2009
- Enable Gzip Compression In Apache HTTPD With Mod_Deflate
- Dangerous Idealism
- Triggering CFForm Validation When Using Ajax
- My Answer To All The New ACTA PIPA SOPA Laws
- How To Install ANT-Contrib
- Peter Schiff On Ben Bernanke's Mistakes Over Last 3 Years
- Setting Session Cookies Secure In ColdFusion
- June
- May
- April
- March
- February
- January
- 2011
- December
- November
- September
- August
- July
- June
- Understanding The Different CFC Instantiation Behaviours
- Dont Call Us PIIGS
- Be Careful With ColdFusion Date Validation
- CF9 CF8 Railo Multiserver Install Under JRUN
- Your Privacy vs Technology
- How To Install CouchDB On Slackware
- Fixing Retweet.js
- Programmers Put Down The Keyboard
- How To Create A Virtual CFIDE Directory Mapping In Apache
- May
- April
- March
- February
- January
- 2010
- December
- November
- October
- September
Tag Listing
- CFML
- Database
- Front End Design & Development
- Linux
- Other
- America (7)
- Android (1)
- Apache (17)
- Book Review (1)
- Cassandra (13)
- Consulting (1)
- Economics (6)
- Email (2)
- Europe (1)
- Excel (2)
- FaceBook (1)
- Finances (3)
- Google (1)
- html5 (1)
- Humour (1)
- IIS (8)
- Ireland (5)
- Java (11)
- JRUN (3)
- Migration (2)
- mobile (1)
- Networking (2)
- nsfw (1)
- OAuth (1)
- Open Source (3)
- Opinion (10)
- Other (25)
- Performance (6)
- Personal (5)
- PHP (1)
- Politics (2)
- Privacy (2)
- Rant (13)
- REST (1)
- Sailing (1)
- Security (20)
- SEO (6)
- Social Networking (2)
- Software Design (1)
- SOLR (2)
- ssl (2)
- survey (1)
- Ubuntu (3)
- Windows (7)
- Tools & Testing
Reader Comments