【问题标题】:Rails 3 - Speed up Console Loading TimeRails 3 - 加快控制台加载时间
【发布时间】:2011-06-11 19:33:12
【问题描述】:

我想知道是否有任何相对简单的方法可以加快我的控制台加载时间,它开始接近 30 秒。我有很多子类的方法似乎不受reload! 的影响,所以我最终打开和关闭了很多控制台。 IRB 加载快如闪电。

我的宝石太多了吗?如何对加载任务进行计时,以便查看占用最多时间的内容?如您所见,我已经尝试过 dev-boost gem 无济于事。该应用程序在Passenger中很好,只是控制台加载使我大吃一惊。在具有 2.4GHz 和 4GB RAM 的 MBP OSX 10.6.6 上运行。不使用 RVM。

版本:

Ovid$ rails -v
Rails 3.0.3
Ovid$ ruby -v
ruby 1.9.2p136 (2010-12-25 revision 30365) [x86_64-darwin10]

内存:

Ovid$ vm_stat
Mach Virtual Memory Statistics: (page size of 4096 bytes)
Pages free:                         118818.
Pages active:                       341320.
Pages inactive:                      99490.
Pages speculative:                  310576.
Pages wired down:                   112527.
"Translation faults":             23097323.
Pages copy-on-write:               1270961.
Pages zero filled:                13836659.
Pages reactivated:                      36.
Pageins:                            165761.
Pageouts:                                0.
Object cache: 28 hits of 760846 lookups (0% hit rate)

宝石文件:

source 'http://rubygems.org'

gem 'rails', '3.0.3'
gem 'mysql2'
gem 'foreigner'
gem 'haml'
gem 'capistrano'
gem 'nokogiri'

#web services
gem 'yammer4r'
gem 'ruby-freshbooks'

#authentication gems from nifty generator
gem "bcrypt-ruby", :require => "bcrypt"
gem "mocha", :group => :test
gem 'authlogic'

#dev
group :development do
  gem 'rails-dev-boost', :git => 'git://github.com/thedarkone/rails-dev-boost.git', :require => 'rails_development_boost'
end

#testing
group :test do
  gem 'database_cleaner'
  gem 'cucumber-rails'
  gem 'cucumber'
  gem 'rspec-rails'
  gem 'spork'
  gem 'launchy'
  gem 'machinist'
  gem 'faker'
  gem 'capybara'
end

非常感谢!

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-3 console


【解决方案1】:

我终于使用 Benchmark 找到了我的启动瓶颈。特别是,导航到 bundler gem 并在 lib/bundler/runtime.rb 中找到执行 Kernel.require 的行并将其包装如下:

puts Benchmark.measure("require #{file}") {
  Kernel.require file
}.format("%n: %t %r")

您可能需要在应用中的某处添加 require 'benchmark',例如在 config/boot.rb 中。这将告诉您需要多长时间才能需要每个宝石。我不能保证您的结果会与我的结果相匹配,但与大多数情况下的亚毫秒相比,我有一些宝石的加载时间超过一秒。一些是我不需要开发的宝石,但我确实需要开发环境中的一些任务,例如卡皮斯特拉诺岛,应该我对启动的其他领域(初始化程序等)进行了基准测试,但找不到任何重大瓶颈。

我还没有想出一个干净的方法来配置应用程序,只为真正需要的任务加载那些。可能,我可以创建一个名为 :speedy 的环境,并在我知道不需要这些 gem 时使用 RAILS_ENV=speedy rails s/c 进行启动。然后在 Gemfile 中,我可以使用 group :speedy 在某些情况下排除这些 gem。

话虽如此,对我来说最大的启动烦恼是必须加载整个环境来运行 rake 任务。我可能会为此排除大多数宝石,但 Gemfile 会开始变得混乱,所以我不知道是否值得。

【讨论】:

  • 这个 hack 提供了一些非常有趣的数据。我想知道有多少 gem 作者意识到他们的工作对冗长的启动时间有多大影响。
  • 这个输出在哪里显示?我虽然有日志文件,但我什么也没看到。甚至尝试了通用的 put 并验证我正在修改正确的 runtime.rb。我错过了什么?
  • 标准 - 通常是运行 Rails/Ruby 进程的终端/命令窗口。
  • 感谢您的提示。这真的很有帮助。 @Bob Benedict:创建一个新的 rails 应用程序,cd 进入新的应用程序文件夹并输入:rails g。当我想查看输出时,它对我有用
  • 很棒的提示。我们已经看到了一些疯狂的加载时间,这对于帮助隔离问题 gem 等很有用。它确实应该是 bundler 的默认选项。此外,有没有办法将此扩展为一般 ruby​​ 脚本消耗 > 1 秒的方法?
【解决方案2】:

稍微适应的形式,可复制粘贴,包装所有需求,并提供可排序的输出:

# Add this to the top of boot.rb
require 'benchmark'
def require(file)
  puts Benchmark.measure("") {
    super
  }.format("%t require #{file}")
end

然后你可以执行 no-op 来查看它们:

rails runner 1

或者对它们进行排序并显示前 50 个:

rails runner 1 | sort -nr | head -n 50

【讨论】:

  • 对于 rails 2.3/ruby 1.8.7 使用 script/runner 1
  • 您节省了我们的 2 天时间 :)
  • 我得到这个错误:C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler.rb:85:in `ui' : 在运行 Bundler 2.1.4 的 Ruby 2.6.6 和 Rails 5.1.7 上未初始化的常量 #::UI (NameError)
【解决方案3】:

您可以通过将 :require => nil 添加到缓慢的 Gemfile 条目并手动要求它们来加快速度。 例如

gem 'jammit', :require => nil

我还在一次聚会中解决了这个问题。 这似乎是 ruby​​ 1.9.2 中的一个错误(请参阅此补丁的 cmets:https://gist.github.com/1008945

您可以通过我刚刚链接的要点修补您的1.9.2 或升级到1.9.2-head1.9.3-head 来修复它。

【讨论】:

  • 听起来是个好主意。我们看到像 activeadmin 和 omniauth 这样的 gem 需要时间来加载,因此想知道在不影响任何功能的情况下稍后加载它们的最佳策略是什么。在 rails 完全加载后手动要求这些的最佳位置在哪里?
【解决方案4】:

这绝对是关于清理你的代码和识别瓶颈,但是一旦你节省了这些钱,就值得看看像 Zeus 这样的东西来加快你的开发时间。

gem install zeus

https://github.com/burke/zeus(文档)

它并非没有错误,有时确实需要重新启动,但我仍然看到在小的代码更改后通过快速服务器和控制台重新启动,开发时间总体上增加了。

【讨论】:

    【解决方案5】:

    我只能建议穿上你的白大褂,把问题一分为二。看看注释掉你所有的 gem 需求是否会加快速度(大概这还涉及注释掉依赖这些 gem 的代码片段)。如果是这样,一次注释掉一半,依此类推。

    抱歉,这不是一个真正的答案。我想您可以尝试 ruby​​-prof,例如使用 rails runner 和无操作脚本调用它。

    我在我的 Mac 上尝试了ruby-prof script/rails runner 'nil',但它似乎刚刚崩溃:-)

    编辑

    如果您将 git 用于您的应用程序,您也可以尝试它的 bisect 命令,看看是否有一个特定的时间点让事情变慢,而不仅仅是一般的膨胀。

    【讨论】:

      【解决方案6】:

      重新加载!一段时间以来一直是个问题。看看this。您可以使用一些补丁程序以及一些关于如何解决问题的提示。

      reload 方法本身如下所示。

      # reloads the environment
      def reload!(print=true)
        puts "Reloading..." if print
        ActionDispatch::Callbacks.new(lambda {}, false).call({})
        true
      end
      

      您总是可以将您的环境添加到此方法中以覆盖它的功能并强制您需要重新加载。

      这对我有用,所以如果它对你有用,请告诉我们。一切顺利。

      【讨论】:

      • 感谢您的建议——我尝试了您的补丁和线程中另一个更长的补丁。但我没有任何运气。你的意思是这行应该是 ActionDispatch::Callbacks.new(Proc.new {}, false).call(RAILS_ENV),对吧?
      【解决方案7】:

      非常古老的问题和答案,但它仍然是一个有用的......

      不知何故,jqr 答案出现错误,这似乎与自动加载有关(rails 5.2...)。

      -e:1:in `<main>'                                                                                                                                                                                           
      0.002514 require i18n/config                                                                                                                                                                               
      .../vendor/bundle-dev/ruby/2.7.0/gems/i18n-1.8.7/lib/i18n.rb:19:in `<module:I18n>': uninitialized constant I18n::Config                                           
      Did you mean?  RbConfig (NameError)                                                 
      

      已修复:

      # Add this to the top of boot.rb
      require 'benchmark'
      def require(file)
        mod = nil
        puts Benchmark.measure("") {
          mod = super
        }.format("%t require #{file}")
        mod
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-21
        • 2011-10-29
        • 1970-01-01
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        相关资源
        最近更新 更多