Ruby on rails 在开发模式下加载rails代码库需要很长时间

Ruby on rails 在开发模式下加载rails代码库需要很长时间,ruby-on-rails,performance,Ruby On Rails,Performance,我的一个rails应用程序是一个Rails2.2应用程序,代码库很大。突然之间,在开发模式下,它似乎非常慢。这主要是由于 config.cache\u classes=false config/environments/development.rb中的选项-当我将其设置为true时,它将恢复正常。我希望缺少缓存会使它变慢,但我看到的速度变慢的程度是荒谬的:有时在日志中发生任何事情之前,需要等待30秒!一旦我在日志文件中看到开始发生的事情,页面构建就会正常进行。我想这是最近才开始发生的,但我不知道

我的一个rails应用程序是一个Rails2.2应用程序,代码库很大。突然之间,在开发模式下,它似乎非常慢。这主要是由于

config.cache\u classes=false

config/environments/development.rb中的选项-当我将其设置为true时,它将恢复正常。我希望缺少缓存会使它变慢,但我看到的速度变慢的程度是荒谬的:有时在日志中发生任何事情之前,需要等待30秒!一旦我在日志文件中看到开始发生的事情,页面构建就会正常进行。我想这是最近才开始发生的,但我不知道我能做些什么来触发它

有人知道我如何调查这个问题吗?我现在要做的就是在30秒的时间里,日志文件中什么都没有发生

感谢你的指点-max

编辑-刚刚注意到,当我关闭mongrel_rails(我使用它在开发模式下运行应用程序)时,我收到以下消息:
Mon-Jul-25 16:28:06+0100 2011:由于“关机”,为速度慢的工人收获5个线程。

这也许可以解释疯狂的减速,但我不知道为什么会有5个线程在运行

EDIT2-此应用程序在ruby 1.8.6 rvm中运行,但切换回ruby系统(也是1.8.6)没有帮助


EDIT3-刚刚做了一个实验,然后重新加载在我的控制台中需要28秒。这就是问题所在。我只是不明白为什么要花这么长时间。

我找到了导致它的原因,这非常令人惊讶

答案的简短版本:

我的应用程序的路径变得很长,这使得某个地方的正则表达式需要很长时间来测试包含该文件路径的字符串

答案的长版本:

一次疯狂的调试任务*之后,我发现了令人不快的一行:它位于
lib/localization.rb
,第56行:

  filename =~ /(([a-z]+_?)+)\.yaml$/
它为我运行这行两次,为
lang
文件夹中的每个yaml文件运行一次。真正疯狂的是“filename”的值是

“/home/max/work/rails\u apps/e\u learning\u resource\u container/e\u learning\u resource/lang/en.yaml”

“/home/max/work/rails\u apps/e\u learning\u resource\u container/e\u learning\u resource/lang/localizations.yaml”

而且,如果我在我的控制台中运行正则表达式来处理这个问题,我也会得到一个巨大的延迟。因此,问题是针对这些特定字符串测试正则表达式。我只是做了一些实验来研究正则表达式需要多长时间才能完成,你可以看到,每增加一个字母,它的时间就会翻倍:来自irb(所以与我的应用程序无关,只是普通的irb)

因此,正则表达式开始真正与字符串斗争。如果我改变正则表达式使它

/([a-z]+?)\.yaml$/

而不是

/([a-z]+?+)\.yaml$/

,即移除内支架周围的(+),这样就可以了:超快速

在localization.rb中,这句冒犯性的话毫无用处!这是包含这一行的整个块:

Dir[RAILS_ROOT + '/lang/*.yaml'].each do |filename|
  filename =~ /(([a-z]+_?)+)\.yaml$/
  hash = YAML::load(File.read(filename))
  file_charset = hash['file_charset'] || 'ascii'
  lang = $1

  # convert string keys to symbols
  symbol_hash = Hash.new
  Iconv.open(CONFIG[:web_charset], file_charset) do |i|
    hash.each do |key, value|
      symbol_hash[key.to_sym] = i.iconv(value)
      if key =~ /^active_record_errors_(.*)/
        I18n.t("activerecord.errors.messages")[$1.to_sym] =
          symbol_hash[key.to_sym]
      end
    end
  end
这里第2行的正则表达式测试字符串,但不处理结果。这不是说

它只是测试它,没有明显的原因。所以,我们有一个正则表达式,它爆炸了,长字符串被无缘无故地使用。双重失败。这可能是这个模块的旧版本,老实说,我甚至不知道它是如何进入我们的代码库的。转到git,对我的固定版本(只删除该行)发出拉取请求

*如果有人想知道我的mad调试任务是由什么组成的,我做了以下操作,在我的应用程序中的每个rb文件的开头和结尾添加了一行调试代码

#get every rb file in the working folder
old_filecount = nil
files = []
fstring = "*/"
count = 0
folder = "./"
while old_filecount != files.size
  old_filecount = files.size
  files += Dir[File.join(folder,fstring*count, "*.rb")]
  count += 1
end  
#spam debugging into start and end of every file
files.each do |file|
  `sed '1i\\\nputs \"#\{Time.now} - #\{__FILE__}:#\{__LINE__}\"\' #{file} > tmp.txt;mv tmp.txt #{file}`
  `echo \";puts \\\"#\{Time.now} - #\{__FILE__}:#\{__LINE__}\\\"\" >> #{file}`
end

哈奇,嗯。

我找到了导致它的原因,这非常令人惊讶

答案的简短版本:

我的应用程序的路径变得很长,这使得某个地方的正则表达式需要很长时间来测试包含该文件路径的字符串

答案的长版本:

一次疯狂的调试任务*之后,我发现了令人不快的一行:它位于
lib/localization.rb
,第56行:

  filename =~ /(([a-z]+_?)+)\.yaml$/
它为我运行这行两次,为
lang
文件夹中的每个yaml文件运行一次。真正疯狂的是“filename”的值是

“/home/max/work/rails\u apps/e\u learning\u resource\u container/e\u learning\u resource/lang/en.yaml”

“/home/max/work/rails\u apps/e\u learning\u resource\u container/e\u learning\u resource/lang/localizations.yaml”

而且,如果我在我的控制台中运行正则表达式来处理这个问题,我也会得到一个巨大的延迟。因此,问题是针对这些特定字符串测试正则表达式。我只是做了一些实验来研究正则表达式需要多长时间才能完成,你可以看到,每增加一个字母,它的时间就会翻倍:来自irb(所以与我的应用程序无关,只是普通的irb)

因此,正则表达式开始真正与字符串斗争。如果我改变正则表达式使它

/([a-z]+?)\.yaml$/

而不是

/([a-z]+?+)\.yaml$/

,即移除内支架周围的(+),这样就可以了:超快速

在localization.rb中,这句冒犯性的话毫无用处!这是包含这一行的整个块:

Dir[RAILS_ROOT + '/lang/*.yaml'].each do |filename|
  filename =~ /(([a-z]+_?)+)\.yaml$/
  hash = YAML::load(File.read(filename))
  file_charset = hash['file_charset'] || 'ascii'
  lang = $1

  # convert string keys to symbols
  symbol_hash = Hash.new
  Iconv.open(CONFIG[:web_charset], file_charset) do |i|
    hash.each do |key, value|
      symbol_hash[key.to_sym] = i.iconv(value)
      if key =~ /^active_record_errors_(.*)/
        I18n.t("activerecord.errors.messages")[$1.to_sym] =
          symbol_hash[key.to_sym]
      end
    end
  end
这里第2行的正则表达式测试字符串,但不处理结果。这不是说

它只是测试它,没有明显的原因。所以,我们有一个正则表达式,它爆炸了,长字符串被无缘无故地使用。双重失败。这可能是这个模块的旧版本,老实说,我甚至不知道它是如何进入我们的代码库的。转到git,对我的固定版本(只删除该行)发出拉取请求

*如果有人想知道我疯狂的调试任务包括什么,我做了下面的事情