我發現是什麼導致它,它是相當驚人的。答案
短版:
到我的應用程序的路徑已經得到了很長時間,這使得正則表達式的地方需要很長的時間來檢驗含有文件路徑的字符串。
回答長版:
一個瘋狂的調試任務*後來我發現違規行:它在lib/localization.rb
56行:
filename =~ /(([a-z]+_?)+)\.yaml$/
它運行這一行兩次對我來說,一旦對於lang
文件夾中的每個yaml文件。什麼是真正的堅果是,「文件名」的值是
"/home/max/work/rails_apps/e_learning_resource_container/e_learning_resource/lang/en.yaml"
和
"/home/max/work/rails_apps/e_learning_resource_container/e_learning_resource/lang/localizations.yaml"
,如果我在我的控制檯運行鍼對這個正則表達式,我得到了大規模的延遲有以及。所以,問題是針對這些特定的字符串測試正則表達式。我只是做了一些實驗,爲需要多長時間正則表達式來完成的,你可以看到,它的倍增時間與每個額外的字母:從IRB(所以沒有什麼與我的應用程序做,只是普通的IRB)
ruby-1.8.6-p420 :023 > 10.times do |i|
ruby-1.8.6-p420 :024 > string = "#{string1}#{"a"*i}#{string2}"
ruby-1.8.6-p420 :025?> time = Time.now
ruby-1.8.6-p420 :026?> string =~ /(([a-z]+_?)+)\.yaml$/
ruby-1.8.6-p420 :027?> puts "#{string} -> #{Time.now - time}s"
ruby-1.8.6-p420 :028?> end
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_/lang/en.yaml -> 0.133935s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_a/lang/en.yaml -> 0.149782s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aa/lang/en.yaml -> 0.198117s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaa/lang/en.yaml -> 0.316208s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaa/lang/en.yaml -> 0.501882s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaa/lang/en.yaml -> 0.896808s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaa/lang/en.yaml -> 1.707035s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaaa/lang/en.yaml -> 3.322242s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaaaa/lang/en.yaml -> 6.613822s
/home/max/work/rails_apps/e_learning_resource/e_learning_resource_aaaaaaaaa/lang/en.yaml -> 13.399231s
所以,正則表達式開始真正與字符串鬥爭。如果我改變了正則表達式,以便它的
/([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的正則表達式在這裏測試字符串,但並沒有對結果什麼。也就是說,它不說
if filename =~ etc
...do something
它只是測試中,它沒有明顯的原因。所以,我們已經得到了一個正則表達式,可以用任何理由使用長字符串。雙重失敗。這可能是這個模塊的舊版本,我甚至不知道它是如何進入我們的代碼庫,說實話。關閉以便爲我的固定版本(僅刪除該行)提出請求。 *如果有人想知道我瘋狂的調試任務包括什麼,我做了以下操作來在我的應用程序中爲每個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
hacky呃。
只適用於Rails3:https://github.com/paneq/active_reload – apneadiving
你最近從ruby 1.8切換到1.9了嗎? – house9
@ house9 - 不,它是一個紅寶石1.8.6環境,通過RVM加載。我想知道是否是由於切換到rvm引起的,我剛剛爲這個應用程序做了最近的改變,但是將rvm切換回系統並再次啓動應用程序沒有任何區別。 –