Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 759
astropanic Avatar asked Dec 16 '10 13:12

astropanic


People also ask

Why is rails so slow?

There are only two reasons why Rails application might be slow: Ruby and Rails are used where other tool might be a much better choice. Too much memory is consumed and hence garbage collection takes too long.

How do I fix slow code in Ruby?

To do this, we use the TracePoint API in Ruby to hook into every single method call made by Ruby. Similarly, for object allocations, we use the ObjectSpace module to trace object allocations, or even dump the Ruby heap to observe its contents. rbspy samples stack frames from a Ruby process over time.

Is Ruby a performant?

Being an interpreted language, Ruby is not as performant as C/C++, Rust, and Go. Although not impossible, it is hard to scale a Ruby on Rails application. Moreover, the lack of static types in Ruby makes it hard to refactor code as the development team grows.


1 Answers

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.

like image 80
robokopp Avatar answered Oct 12 '22 13:10

robokopp