简体   繁体   中英

slow rails stack

When I run

rails server

or

rake -T

or some other rails script, it takes a lot of time, approx 1 minute. What is the best way to determine what exactly is so slow ? How can the speed be improved ?

Rails v is 3.0.3 run trough ruby 1.9.2 (RVM) - Linux

That is bothering me also, since I have switched to Rails 3.

To your second question: I found by digging through the framework that the initializers take about half the time of a simple rake or rails call before it actually starts doing its task.

If you put these simple timing lines into the loop of initializer calls in $GEM_PATH/gems/railties-3.0.3/lib/rails/initializable.rb (or piggy-back it if you like):

def run_initializers(*args)
  return if instance_variable_defined?(:@ran)
  t0 = Time.now
  initializers.tsort.each do |initializer|
    t = Time.now
    initializer.run(*args)        
    puts("%60s: %.3f sec" % [initializer.name, Time.now - t])
  end
  puts "%60s: %.3f sec" % ["for all", Time.now - t0]
  @ran = true
end

EDIT: Or, for railties 4.2.1:

def run_initializers(group=:default, *args)
  return if instance_variable_defined?(:@ran)
  t0 = Time.now
  initializers.tsort.each do |initializer|
    t = Time.now
    initializer.run(*args) if initializer.belongs_to?(group)
    puts("%60s: %.3f sec" % [initializer.name, Time.now - t])
  end
  puts "%60s: %.3f sec" % ["for all", Time.now - t0]
  @ran = true
end

... you can follow up what happens. On my system, which is a 2.4 Core 2 Duo MacBook the initializers take about 7 seconds.

There are a few that are especially slow on my system. When I filter all out below a second, I get this result on my system:

                load_active_support: 1.123 sec
active_support.initialize_time_zone: 1.579 sec
                       load_init_rb: 1.118 sec
                set_routes_reloader: 1.291 sec

I am sure somebody (is it me?) will take some time to start there and optimize.

Our Rails 3.1 startup time was almost 1 minute (having a lot of gems)

Then we found out about some Ruby 1.9.3 tuning options on reddit: http://www.reddit.com/r/ruby/comments/wgtqj/how_i_spend_my_time_building_rails_apps/c5daer4

export RUBY_HEAP_MIN_SLOTS=800000
export RUBY_HEAP_FREE_MIN=100000
export RUBY_HEAP_SLOTS_INCREMENT=300000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=79000000

put this in your shell environment/profile/bashrc, and you are done.

We boosted our startup from 1 minute to 9 seconds

One workaround I use for this is to preload the rails environment with rails-sh . That way only the first rails/rake command is slow and the rest are pretty fast. Wrote a fuller answer to it in this question .

Another way I tried more recently and is compatible with the first is installing a patched ruby (with rvm or rubyenv or from source) and adjusting environment variables (see @stwienert's answer). The falcon patch and railsexpress patches both seem to pick up significant performance in ruby 1.9. Check out rvm/rubyenv on how to install patched rubies with them.

I used robokopp 's tip here to discover that most of the time was being used in the build_middleware_stack and load_config_initializers steps for me. This is because I am using the omniauth gem that adds middlewares and perhaps has heavy initialization steps. I am on Rails 3.1.rc1, and my initialization takes almost 13 seconds (I am on ruby 1.9.2p180).

Even for brand new rails 3.1.rc1 app, the initialization takes ~3.6 seconds, with max time taken by load_config_initializers .

So I suggest you look for gems/your own code that have heavy initializers or add too many middlewares.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM