1

我的规范代码的运行时间比预期的要长很多,但当我尝试在 下运行它们时rspec-prof,问题似乎消失了。最终,我追踪到rake本地运行与在解释器下运行的差异。

跑步只rake需要 75 秒,而跑步ruby $(which rake)只需要 12 秒。这速度快了五倍多。看一看:

$ rake
~/.rvm/rubies/ruby-1.9.2-p320/bin/ruby -w -S rspec spec/args_spec.rb spec/levels_spec.rb spec/opts_spec.rb spec/run_spec.rb spec/split_spec.rb spec/unit_spec.rb
~/.rvm/gems/ruby-1.9.2-p320/gems/bundler-1.2.3/lib/bundler/source.rb:516: warning: method redefined; discarding old revision
..................................................

Finished in 1 minute 14.39 seconds
50 examples, 0 failures

$ ruby `which rake`
~/.rvm/rubies/ruby-1.9.2-p320/bin/ruby -w -S rspec spec/args_spec.rb spec/levels_spec.rb spec/opts_spec.rb spec/run_spec.rb spec/split_spec.rb spec/unit_spec.rb
..................................................

Finished in 12.88 seconds
50 examples, 0 failures

查看rake“#!”中显示的“包装二进制文件”的内容 它在解释器下运行的行 - ruby_noexec_wrapper- 并且确实将命令运行为:

ruby_noexec_wrapper $(which rake)

给出同样缓慢的 75 秒运行。

任何想法为什么会这样?

除了避免直接运行 rake 之外,还有什么可以改进的吗?既然这是将 gem 包装成二进制文件的标准方法,那难道不会减慢所有 gem 打包工具的速度吗?

4

1 回答 1

1

我们看一下ruby_noexec_wrapper文件(rvm 1.16.17):

#!/usr/bin/env ruby

original_file=ARGV[0]
ARGV.shift
$PROGRAM_NAME=original_file

require 'rubygems'
begin
  require 'rubygems-bundler/noexec'
rescue LoadError
  warn "unable to load rubygems-bundler/noexec" if ENV.key?('NOEXEC_DEBUG')
end

eval File.read(original_file), binding, original_file

据我所知,两个警告区域是两个require语句。第一个,require 'rubygems',不太可能是一个问题,因为 ruby​​ 1.9+会自动执行此操作

我认为问题出在require 'rubygems-bundler/noexec'. 如果你看看它在做什么,你会发现它正在设置捆绑器。这涉及到需要 gem,这可能是您启动缓慢的根源。

宝石在加载时不应该做很多事情,但不幸的是,他们中的许多人在这方面犯了一些错误。解决此问题的唯一方法是尝试找出导致大部分缓慢的宝石,并在可能的情况下找到替代方案。

于 2013-03-22T15:45:01.657 回答