At FiveRuns, we have a set of installed clients which upload data to our service periodically. Because of the way it is implemented, Rails is quite slow in handling file uploads. Merb is an alternative, albeit much simpler, stack to Rails which handles file uploads in a much saner manner. The performance difference is quite large.
Optimizations
Merb - turned off ActiveRecord, environment to production, log level to warn, disabled sessions globally.
Rails - environment to production, log level to warn, disabled sessions for the controller.
The Merb controller code:
def put
FileUtils.mv params[:file][:tempfile].path, MERB_ROOT+”/uploads/#{params[:file][:filename]}.#{next_count}”
render :action => ‘index’
end
The Rails controller code:
def put
File.open(RAILS_ROOT+"/uploads/#{params[:file].original_filename}.#{next_count}”, “w”) { |f| f.write(params[:file].read) }
render :action => ‘index’
end
I used Apache JMeter to create a group of 25 users trying to upload a 250k image as fast as possible. On a side note, I can’t recommend JMeter highly enough. I downloaded it and was generating this load within 10 minutes. The user manual walked me through the basics and the UI had exactly the controls I need to create the FORM POST.
Without further ado, here’s the results.
I’m not sure how to read these results. Merb’s average response time is 16 ms while Rails’s average is 205 ms (over 10x faster), yet the throughput is 3000 vs 2000 req/min (only 50% greater). Note that Merb seems to be much more deterministic in the response times. Rails response handling times appear to fluctuate wildly while the Merb results have a much tighter standard deviation. These results remind me of the old proverb: “Data is not information and information is not knowledge”. While the specifics are still a little unclear, it is clear to me that Merb is several times faster than Rails at just handling file uploads.
3 responses so far ↓
1 Tom Mornini // Oct 3, 2007 at 11:55 am
Hello Mike. Thanks for writing this nice post on Merb!
Did you turn off locking?
By default, Merb will lock through the controller code, serializing that portion of the requests. This is required for ActiveRecord code to behave, as AR is not thread safe.
The Merb responses are quicker because it’s threaded up to that point, whereas Rails locks for *everything*.
If you add:
:use_mutex: false
in merb.yml
You’ll get better results yet.
2 mperham // Oct 4, 2007 at 12:19 pm
Thanks Tom, that’s good info to have; I didn’t use it because it’s not documented. Could you add it to the merb.yml (commented out like the other various options) so that people know about it in future releases?
3 800 Steps To Go » Blog Archive » Rails Performance: A Brief History of the Universe // Jan 28, 2008 at 4:12 am
[...] that makes an effort at better performance. Entries from this side of the arena include Grails and Merb. The question I’d be asking myself if I were a Rails evangelist that wanted to see the [...]
Leave a Comment