6 ms·
I've been a Rails dev for 5 years. I'm frequently considering leaving for another framework because of one thing: bootstrap time. Starting a test or server on m
by aneth 15y ago
I've been a Rails dev for 5 years. I'm frequently considering leaving for another framework because of one thing: bootstrap time. Starting a test or server on my dev machine takes 20-30 seconds. Particularly with tests, this is a huge problem for doing proper TDD, particularly when you are trying to use tests to track down a bug. In that 20-30 seconds, I often console myself that we no longer need to print punch cards and wait a whole day, but that's little consolation when node.js starts up in under a second.
There are hacks and fixes to this like spork, but none of this should be necessary. The performance issues are not debated in the open enough. I don't understand how those startup times are acceptable to anyone, but I rarely get responses when I ask questions about it.
http://stackoverflow.com/questions/5738443/why-is-rails-bootstrap-so-slow-and-what-can-i-do-about-it http://stackoverflow.com/questions/5738443/why-is-rails-boot...
UPDATE: I have the latest top of the line Macbook Air - 2.13 Ghz Core 2 Duo with SSD.
I have other issues with Rails, but this is the only potential deal breaker. (I tend toward functional clarity instead of "human" readability in the magic debate, while most "Rubyists" would rather pollute the namespace (e.g. metawhere) and create 100 line method_missing calls to make one command slightly prettier aesthetically. And Cucumber - ugh what a ridiculous contraption that is.)
- jpr 15y agoHow often do you need to endure that 20-30 second startup time? Is it every time you change anything?
- joevandyk 15y agoDuring deploys, running a test, configuration changes, starting anything that loads the whole rails environment.
- aneth 15y agoPretty much ANYTHING you do. Start a console, start a server, run a test, migrate your database, run a rake task. It's a huge productivity killer for me. And as other comments have stated, it's surprising this issue is not discussed more.
- aaronblohowiak 15y agoNot solutions, but workarounds: Keep console open and use reload! when you change your models, for starting a server I don't have much other than keep it running the background, running a test -- use spork, migrate your db and run rake tasks -- try to take advantage of the fact that you can specify multiple rake tasks at a time; "rake db:migrate db:test:prepare"
- aneth 15y agoMore good suggestions. I'd love to get spork working, but rspec syntax makes me cringe and I haven't gotten it to work with test-unit. I found a plugin and a fork, neither of which I could get working.
- theli0nheart 15y agoI haven't been using Rails for nearly as long as you have. As a result, I thought the bootstrap time was something Rails developers just "put up with". I would have thought that someone else would have noticed this problem and done something about it...surprisingly I don't think many have. Django, by comparison, bootstraps the environment almost instantly. I have also been looking for an answer for how to deal with this issue, so I just started a bounty on your question for 200 reputation. Looking forward to a good answer; it may very well convince to go back to Rails.
- aneth 15y agoYeah, I tried Django 2 years ago and sort of wish I had stuck with it primarily for this reason. (Additionally I much prefer the Python "no magic" philosophy, although I've gotten used to tracing through Ruby craziness.) The Rails community (at least at the time) was so much larger and more open that it seemed like a better bet. Rails 3 was coming up and I knew Yehuda was doing brilliant things with the Rails 3.0 architecture. Plus, Moore's law right? - not helping! I'd love for some hard core Rails guys to get in here and offer some real solutions! As much as I have issues with some things about Rails, it is largely a great tool for me, and I know it so well I'd like to be able to continue using it without tearing my hair out every time I need to run a simple test.
- uriel 15y agoSadly this days most Python frameworks (including django) are quite full of all kinds of dark magic. If you want a blissfully magic-free language try Go ( http://golang.org http://golang.org ).
- deleted 15y ago[deleted]
- mrj 15y agoThat's not the dev server, which is able to start and reload pretty fast. That post is complaining about the startup time for loading several pre-forked Python VMs on the first request. That's pretty much a production problem. It's somewhat common to see "warmup" scripts that make sure all the VMs start. The OP was talking about development time.
- joevandyk 15y agoOne thing I've been investigating is using RabbitMQ to separate the logic out of the monolithic rails application. Beetle looks promising. http://xing.github.com/beetle/ http://xing.github.com/beetle/ You can do both RPC and async messaging. (Might want to wait a few days before using it, there's issues with some libraries that it depends on that will be fixed soon).
- aneth 15y agoI don't understand how that helps. This is a problem for pretty simple Rails applications. Besides, why should I have to set up and learn RabbitMQ to have a decently performing web framework? This is 2011 and this shit is slower than my old Java framework running on an ancient processor in 1995.
- bphogan 15y agoI dunno, I've been at this for 6 years with Rails, am running a 4 year old mbp that dogs it with Java stuff but hangs in ust fine with Ruby. Maybe my apps aren't nearly as huge as the ones you're loading, but I've done some large ones. But I share your frustrations re: "metawhare" :) Solution is just to hang around with responsible devs.
- carbon8 15y ago"Starting a test or server on my dev machine takes 20-30 seconds. Particularly with tests, this is a huge problem for doing proper TDD" Long startup times or not, sounds like you should probably be using autotest or watchr. 20-30 seconds is not normal. Unless the app has a very large amount of code and dependencies, that sounds like an environment issue. "while most "Rubyists" would rather pollute the namespace" That's unfair, and I say that as someone who is very adamant about clarity, explicitness and simplicity in my apps. In my experience, most (not all, but most) of the libraries where people are doing weird things are libraries that are far from necessary, so avoiding that is trivial. For instance, you cite metawhere. First, I haven't investigated the implementation in depth, but, FYI, it doesn't appear to use method_missing at all. Secondly, I'd be very hesitant to include a library like this in an app, regardless of the implementation, since it's too invasive of a dependency.
- joevandyk 15y agoautotest or watchr doesn't help startup times -- I'm not sure why you mentioned that here. I don't think the performance problems are affecting ALL applications - some people don't see any problems. I do think there is something wrong in Ruby or Rails that doesn't happen in all code paths.
- aneth 15y agoAutotest doesn't help startup times, but it can help mitigate the problem somewhat since the tests will start almost instantly when you change a file, saving a few seconds. It's a good suggestion, but doesn't solve the problem.
- carbon8 15y ago"autotest or watchr doesn't help startup times -- I'm not sure why you mentioned that here." If you use autotest or watchr you aren't starting up the environment very frequently.
- joevandyk 15y agoI'm not sure why you think that. Unless you use spork or something that preloads the rails environment then forks it on every test run, autotest/watchr will boot the whole rails environment from scratch on each run.
- philjackson 15y agoI was at the BBC working on a large Perl codebase which was a fairly typical Catalyst/DBIx::Class stack. It had thousands of tests which thanks to the foolish way we loaded reference data and pre-populated memcache etc. had the test suite running for 3 hours. As you can imagine, it was a nightmare for TDD and indeed for large merges (by the time you've run tests trunk would have inevitably changed). We never fixed it thanks to a combination of lazyness and a case of "it's legacy code, won't be around much longer" syndrome. http://qwerly.com http://qwerly.com runs a tight and fast Node.js stack at the front-end with a test suite that takes less than a second to run (a few hundred assertions). I'll dedicate much time to the framework around it's tests and make sure it's never slow.
- aneth 15y ago> with a test suite that takes less than a second to run I'm jealous. That would probably save me a huge portion of my development time. Node is my top contender if I dump rails.
- stiff 15y agoI have investigated this in detail and the reason for this is really ridiciulous - 80% of this time is spend on executing "require" statements and this is due to really bad design of RubyGems and/or Bundler. They both do their job by augmenting $LOAD_PATH to include all directories containing gem contents. If you then look into how Ruby deals with the $LOAD_PATH, it turns out each time you do a "require" it will go through all of those directories and their subdirectories in search for a file matching what you have required. I used strace to see how this impacts doing "rails console" on an application with around 30 gems - it ended up doing 35000 open calls that ended up with ENOENT. It is beyond my mind how this can remain unfixed for so long. If RubyGems instead maintained a cache from all the gem directories, it could map requires to files without touching the filesystem and it would work many times as fast. Even creating a cache at runtime and then using it for the lookup would be many times as fast. Unfortunately, it is hard to determine a strategy for building this cache that would map the requires to files in exactly the same was as RubyGems, because RubyGems has some pretty weird strategy for determining which files take priority over which files when you do an ambiguous require. Because of this, I haven't yet succeeded in implementing a fix myself and I'm not 100% sure if it is possible. I also tried to contact one of the Bundler guys, but so far haven't had any reply about this.
- joevandyk 15y agoAre you sure that the open calls is the reason why 'require' is so slow?
- stiff 15y agoI have just written a short blog post about this: http://www.stifflog.com/2011/05/15/why-is-rails-startup-so-slow/ http://www.stifflog.com/2011/05/15/why-is-rails-startup-so-s... I'm not that deeply in Ruby/RubyGems/Bundler internals to be 100% sure, but on the other hand I really can't see how it could work reasonably fast while using the strategy for looking up libraries it uses.
- aneth 15y agoGreat work! Yehuda is brilliant, although I'm sure he's busy now and I don't know how much bandwidth he would have to address that. I think he's full bore on Sproutcore. If I calculate (20 seconds) x (number of times I bootstrap rails), it might even be worth my time to have a go at it. There is a bug supposed to be fixed in ruby 1.9.3 that addresses something to do with the load path and bootstrap performance, but no idea when that's due to land. If it's truly the cause, it seems like this should be a patch to 1.9.2 instead. You might also want to see if this is related: https://github.com/rdp/faster_require/blob/master/lib/faster_require.rb https://github.com/rdp/faster_require/blob/master/lib/faster...
- joevandyk 15y agoAnother person with a similar problem: http://www.ruby-forum.com/topic/393617 http://www.ruby-forum.com/topic/393617
- joevandyk 15y agoI've started a sample Rails 3 application here: https://github.com/joevandyk/slow-rails https://github.com/joevandyk/slow-rails Other than a fairly standard list of gems in the Gemfile and one Model with two columns, the application is empty. On my machine with Ruby 1.9.2-p180, it takes 20 seconds to start. And the application is empty!
- jshen 15y agoI just tested this on one of my apps (yakkstr.com) and 'rails c' and 'rails s' both startup in about 5 seconds. I'm on 1.8.7 and rails 3, not sure if that makes a difference, but 20-30 seconds doesn't mesh with my experience at all. I'm on a 2.66 GHZ i5 imac, not an SSD.
- joevandyk 15y agoWould you mind testing out https://github.com/joevandyk/slow-rails https://github.com/joevandyk/slow-rails and see how long 'rake' takes to run? For me on 1.8.7, it takes about 7-8 seconds. Annoying because the application is empty, it's just 28 gems being loaded. On 1.9.2, it's 20 seconds or so.
- jshen 15y agoI get the same, I hadn't noticed it because I'm still using 1.8.7 Have you tried spork? https://github.com/timcharper/spork https://github.com/timcharper/spork Also, have you opened a ticket or looked to see if there is one already?
- jshen 15y agohttp://redmine.ruby-lang.org/issues/3924 http://redmine.ruby-lang.org/issues/3924
- hartror 15y agoI had a similar issue using Django+PostgreSQL on Ubuntu 11. Running the test suite was taking 10s of seconds in that combination which wasn't too bad but hurt my test->fix->test cycle when debugging PostgreSQL related issues (during normal dev I run the test suite in a in memory SQLite database). Took a little time to work it out as I am new to PostgreSQL but it was worth it to avoid a pause in the problem solving cycle. Problem and solution explained on my blog: http://www.roryhart.net/code/slow-create-database-with-postgresql/ http://www.roryhart.net/code/slow-create-database-with-postg...
- sunchild 15y agoRe: your knock on Cucumber – isn't Cucumber explicitly designed to enable human readability so that non-programmers can collaborate on features in quasi-colloquial English? Can you expand on what you dislike about it? I'm not trolling; I'm genuinely curious about this.