Update: I highly recommend going with Ruby Enterprise Edition and Evan Weaver’s Ruby GC settings for much improved Ruby speed.
In the past few months, as a result of my clumsiness, I’ve been working on a new, Leopard-enabled MacBook. When replacing my wet and dying Tiger MacBook of yore, my one hope was that my daily executions of rake to test Harvest would execute a little faster. A 20% increase in processor speed doesn’t buy one a whole lot when web programming. The one place I figured I’d see a bump is the constant processor use of rake.
Wrong. So, so, wrong.
After moving to a new MacBook with Leopard installed, I experienced a test suite that ran 2-3 times slower than on my old machine. This became the difference between testing frequently and hardly at all; the difference between using and not using autotest. Pain to the max.
This post is going to get long, so I’m going to reveal now. For me, the issue was resolved by leaving the canonical Hivelogic world and reverting to the default Leopard installation of Ruby. Test speed returned to better-than-normal, and all at the price of only 6 hours of troubleshooting!
MySQL: Like shooting fish in a Superior-sized barrel
As always, my first suspicion was MySQL. I looked through my local Rails logs for particularly slow calls into MySQL. The initial thought was that a few bad-apple tests were not tuned very well for my environment. What I found was everything was slow and there were too many noticeably poor speeds to point to a few SQL calls as the culprits.
Next I compared my my.cnf file to my compadre’s. I noticed no major smells in my file. Since I’m a DB dummy, more important was Dee’s estimation that indeed my configuration file looked alright. We even went so far as comparing MySQL variables from within the MySQL shell:
mysql> show variables;
Finally, I upgraded MySQL from 5.0.51 to 5.0.51b and reinstalled the ruby-mysql gem. No dice.
Sanity check: Benchmark the MacBook
Dee suggested I verify that my new MacBook itself wasn’t a lemon. I was doubtful since I’d noticed no other areas where it performed worse than its predecessor. Still, this was a great place to regroup. Benchmarking each MacBook put my mind in the right place to finish off my troubleshooting and uncover my problem.
I used Xbench to compare the general performance of my new and old MacBooks. Benchmark results favored the new machine everywhere except OpenGL. After reading the FAQ, it’s pretty clear OpenGL is a false positive for the old MacBook.
Rails: A general comparison between two machines
So I knew Rails was running slow when hitting the DB, but what about all by itself? I simply ran rake environment on both laptops and took a mental count. The command took ~3 seconds on the old machine and 6-7 seconds on the new one.
This was really enough, but I did run some model finders in each environment as a sort of sanity check. Performance results were in line with everything you’ve read so far.
Ruby: ActiveRecord-less and slow as ever
To hit the real meat-and-potatoes, I executed some Ruby-only code on both systems, benchmarking the whole way. Old Tiger:
user system total real
#1 0.000000 0.000000 0.000000 ( 0.000217)
New Leopard:
user system total real
#1 0.000000 0.000000 0.000000 ( 0.001347)
Over six times slower. New shit has come to light!
Sanity check II: Another system test
I wanted to run something from the command line that proved the new hotness was outperforming the old hoopty. Enter a little shell script built to copy an empty file to and from a folder 10,000 times:
echo "start at `date +%s`"
touch ./file.txt
mkdir ./fileholder
LIMIT=1000
for ((a=1; a <= LIMIT ; a++))
do
mv ./file.txt fileholder/
mv ./fileholder/file.txt ./
done
rm ./file.txt
rm -rf ./fileholder
echo "end at `date +%s`"
exit 0
Rejoice! The new machine took 32 seconds to execute. The old one executed in 78 seconds. The winnowing process was imperfect, but I believe a winner has been crowned: Ruby.
Ruby: From source to simple
Both machines in question were on Ruby 1.8.6. The new one on patchlevel 114, the old one on 0. I attempted to install Ruby from source for patchlevel 230 (ACK!) and 111. No rake performance improvements were achieved. I also own a Leopard Mac Mini, installed from the Hivelogic instructions, and experienced the same rake downfalls (Sanity check III). Time to try Leopard’s default Ruby (patchlevel 114).
I did not want to remove /usr/local/bin from my path because I have other wonderful things installed there. Advisable or not, I simply renamed key binaries:
mv /usr/local/bin/rake /usr/local/bin/rake.bak
mv /usr/local/bin/irb /usr/local/bin/irb.bak
From there, all my gems needed reinstalled. gem install failed on my first try, but worked thereafter. The ruby-mysql gem had special needs (assuming a Hivelogic-style install of MySQL), which were addressed with:
sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
rake clean. Barry happy.
I can’t say I’m comfortable browsing my filesystem for gem source like I was with /usr/local, but I imagine that will come with time. My suspicion is the Hivelogic instructions can still work in Leopard given the appropriate compilation switches. I’m not the person to provide such information – perhaps someone already has?









Comments (8)
I just realized that I had the same problem. I’m using RSpec a lot and my specs ran 4-5 times slower on my MacBook Pro than on my iMac. I also followed the Hivelogic instructions for compiling and installing ruby. The solution for me was to recompile and reinstall ruby without any explicit options (./configure, make, sudo make install). Specs run blazing fast again, startup time for the rails-environment of a new/empty rails project dropped down from 5 to 1.5 secs…
@Andi Thanks for the comment. I’m sure there are a lot of Rubyists who have this problem but do not know they have this problem. Frankly, I’m surprised this blog post hasn’t gotten more play in the community.
Glad you’re running with speed again!
Thank you Barry & Andi! You have saved me from painfully and untenably long test times! I will think of you both multiple times per day as I run my tests in about a fourth of the time. Thank you, thank you, thank you.
@Jordan Happy that this has saved you some pain. It was excruciating when I was running on the slow rake train!
The running of my test suite dropped from 75s to 20s. They’d started running so slow, that I’d stopped using autospec and started running them individually. Even that was pain.
Thanks!
On a side note, your blog has turned the mysql line double hyphens into m-dash’s!
@Andrew Sounds exactly like the breath of fresh air I received upon fixing this up. Please pass the word on because I’m sure lots more people unknowingly have this problem.
Thanks for letting me know about the m-dashes. Should be fixed up!
Thanks guys, I ran into this also after upgrading to Snow Leopard, and your solution seems to have cut my test time in half.
Update: I highly recommend going with Ruby Enterprise Edition and Evan Weaver’s Ruby GC settings for much improved Ruby speed.