EDIT: Strike that - I just realised one of my apps gets 117,000 ENOENTs from trying to handle require's during startup....
EDIT: I keep wanting to write something to cache the paths, but haven't had time. I'd be perfectly happy to be forced to regenerate cache on first run after any gem update. The 117,000 ENOENT's above comes from ending up with a $LOAD_PATH of about 100 entries, where the worst case causes almost every one of those directories to be checked for both foo.rb and foo.so. Something like 99%+ of startup time of most of my Ruby code is overhead added by rubygems way of handling require.
EDIT: Actually, a lot of this might be down to bundler rather than rubygems in some cases.
EDIT: This is not a robust solution, but this little ugly helper combined with wrapping only the two require statements shown, reduced the number of failed stat() calls for my app from 117,000 to 104,700 on startup...
$orig_loadpath = $LOAD_PATH.dup
require 'bundler/setup'
$full_loadpath = $LOAD_PATH.dup
def with_gems(*gems)
filtered = []
gems.each do |gem|
filtered.concat($full_loadpath.grep(/#{gem}/))
end
$LOAD_PATH.clear
$LOAD_PATH.concat($orig_loadpath)
$LOAD_PATH.concat(filtered)
yield
$LOAD_PATH.clear
$LOAD_PATH.concat($full_loadpath)
end
with_gems('require_relative') { require 'require_relative' if RUBY_VERSION =~ /1\.8/ }
with_gems('amalgalite','arrayfields','fastercsv') { require 'amalgalite' }
EDIT:
Wrapped a handful more require statements with "with_gems". Down to 76,000 failed stat()'s... I should have done this before.EDIT: Yikes. 32,000...
Look, I've never been able to understand the people who think RubyGems is a good distribution mechanism for end users either. But switching to another language altogether seems to throwing out the baby with the bathwater. You can just create a Debian package or something that depends on Ruby. That's exactly what we do with Phusion Passenger.
Have gem dependencies? Vendor them. Not that hard.
But if you have gem dependencies that contain native extensions that aren't distributed by the OS... well then switching to Go starts to make sense.
He actually did mention that in the post, though -- packaging Ruby into the installer -- and mentioned how difficult it is. I've never tried it myself, but I imagine it's pretty tough if, for example, you're distributing to Windows as well (although who uses CLI apps in Windows anymore...?)
Many configurations are done via command line tools actually, more so since PowerShell exists.