Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at cf.Objective() 2012 (Minneapolis, MN) with:

Learning ColdFusion 9: Virtual File System vs. Actual File System

By Ben Nadel on
Tags: ColdFusion

Earlier today, I blogged about the new Virtual File System available in ColdFusion 9. I explained that the virtual file system was just like the actual file system except that you were writing to the "ram://" disk rather than to the hard drive. I wrote that the biggest benefit of this new virtual file system was the performance gain - that it was much less expensive to read and write to RAM than it was to an actual disk. I knew this was true, but I didn't have any numbers to back up the statement. As such, I decided to run a very simple speed test comparing the performance of the virtual file system to the actual file system.

This is not a scientific test by any means; nor, did I run this under any kind of load. But, as both file systems were tested in the same environment, I believe that we can still take away some meaning from the results:

  • <!---
  • Param the url variable for determining which file system
  • to be testing with this execution.
  • --->
  • <cfparam name="url.vfs" type="boolean" default="false" />
  •  
  • <!--- Depending on the URL, figure out the directory. --->
  • <cfif url.vfs>
  •  
  • <!--- Use the virtual file system. --->
  • <cfset workDirectoryPath = "ram://temp/" />
  •  
  • <cfelse>
  •  
  • <!--- Use the actual file system. --->
  • <cfset workDirectoryPath = (
  • getDirectoryFromPath( getCurrentTemplatePath() ) &
  • "temp/"
  • ) />
  •  
  • </cfif>
  •  
  •  
  • <!--- Check to make sure our target directory exists. --->
  • <cfif !directoryExists( workDirectoryPath )>
  •  
  • <!--- Create it so that our file writes don't fail. --->
  • <cfdirectory
  • action="create"
  • directory="#workDirectoryPath#"
  • />
  •  
  • </cfif>
  •  
  •  
  • <!---
  • Read in a file from the actual file system. This is a
  • moderetly sized file at just under 700KB.
  • --->
  • <cfset dataFile = fileRead( expandPath( "./target.jpg" ) ) />
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  • <!--- Get the start time. --->
  • <cfset startTickCount = getTickCount() />
  •  
  • <!--- Loop over the given file system a number of --->
  • <cfloop
  • index="iteration"
  • from="1"
  • to="1000"
  • step="1">
  •  
  • <!--- Create a path variable for a new file. --->
  • <cfset newFilePath = "#workDirectoryPath##iteration#.jpg" />
  •  
  • <!--- If this new file currently exists, then delete it. --->
  • <cfif fileExists( newFilePath )>
  •  
  • <!--- Delete the existing file. --->
  • <cfset fileDelete( newFilePath ) />
  •  
  • </cfif>
  •  
  • <!--- Write the data file to target file system. --->
  • <cfset fileWrite( newFilePath, dataFile ) />
  •  
  • <!--- Read the new file into memory. --->
  • <cfset newFile = fileRead( newFilePath ) />
  •  
  • <!--- Delete the new file. --->
  • <cfset fileDelete( newFilePath ) />
  •  
  • </cfloop>
  •  
  • <!--- Get the end time. --->
  • <cfset endTickCount = getTickCount() />
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!--- Output results. --->
  • <cfoutput>
  •  
  • <p>
  • <cfif url.vfs>
  • Virtual File System
  • <cfelse>
  • Actual File System
  • </cfif>
  • </p>
  •  
  • <p>
  • <strong>Results:</strong>
  •  
  • #numberFormat( (endTickCount - startTickCount), "," )#
  • </p>
  •  
  • </cfoutput>

As you can see from the code, I am running several file checks, reads, and writes over a thousand iterations. I ran this 5 times with the actual file system and another 5 times with the virtual file system (discarding the first few results for compilation and optimization overhead). Here are my results:

Actual File System

  1. Results: 22,407
  2. Results: 23,969
  3. Results: 22,703
  4. Results: 23,860
  5. Results: 20,922
  6. Average: 22,772

Virtual File System

  1. Results: 5,500
  2. Results: 5,594
  3. Results: 5,844
  4. Results: 5,860
  5. Results: 6,000
  6. Average: 5,759

As you can see, accessing ColdFusion 9's Virtual File System is about 4 times faster than accessing the actual file system. Not a bad performance boost for transient files.




Reader Comments

4 times faster is extremely fast. Imagine if a Lambo could go 4 times faster. WOW!

But I have a question how could you put this to practical use? What information could you store in the RAM?

@ Drew & Gareth

I agree with Jody....4 times faster is fast! Not sure what else you would want or could expect.

@ Jody

I am building a back end photo system for a shopping cart admin. Meaning I am building a system that allows admin users with the lack of Photoshop skills to crop, resize, add borders, text and other enhancements to there photos as they upload them into the front end of the store. (all with cfimage and functions!!) Now with the virtual file system I can easily add a small preview window for the user to see their results before finalizing the work. Yes...I could have done this before the virtual way, but it will have a little more zoom zoom this way.

You're writing to RAM though (measured in nanoseconds) vs writing to disk (measured in milliseconds). That is a 1000 times faster access. So, yes, I agree that 4 times faster is "faster", but accessing it from ram vs accessing it from the hard drive isn't showing the gains I was expecting.

Also, to keep in mind, I am running ColdFusion on my work laptop as a stand alone install. This is probably not the most powerful machine.

Hi Ben
I'd be interested in seeing the results if you individually time each discrete action (so separate timings for the deletes, writes and reads), rather than timing all four actions together.

--
Adam

@David,

Only if it requires intermediary file writes. There's nothing about the file system that will speed up the image processing itself.

@Andrew,

I don't think so. If you look at the second test, it's actually lower than the first. I think the ups and downs are just the consequence of other background processes taking processing power.

You're using a mapping for ease and cleaner syntax but this is only accessable from one instance (instance specific) and not across CF servers in a cluster right? CF instances in a multi-node enviornment wouldn't be able to share these "files" written to RAM if they had the same mappings would they?

Ben,

What about this:

ImageCrop(cab,50, 140, 700, 320);
smallImg = Duplicate(cab);
bigImg = Duplicate(cab);
ImageResize(smallImg,156,71,'highQuality');
ImageWrite(smallImg,expandpath('images/#lt.id#-ltt.jpg'),.8,true);
ImageResize(bigImg,700,320,'highQuality');
ImageWrite(bigImg,expandpath('images/#lt.id#-lt.jpg'),.8,true);

It is writing to Disk, How can i change it to use Ram and serve it from there.

Also this piece of code runs every-time the page is requested, so it will probably overwrite the image in RAM or File System

1. Will that effect the Performance again as overwriting in Ram again and again.
2. Will it not occupy more space on RAM rather than on File System.
3. How RAM will clean this Stuff, as i have read in Livedocs, it keeps the data in ram until the server is started.

Regards