2010-03-02 52 views

回答

10

優化爲清楚起見,我寧願以下幾點:

phrase.split(delimiter).collect(&:strip) 

。不過我想你想優化速度。我不知道別人爲什麼在猜測。 只有找出更快的方法是對您的代碼進行基準測試。

確保您調整了基準參數 - 這只是一個示例。

require "benchmark" 

# Adjust parameters below for your typical use case. 
n = 10_000 
input = " This is - an example. - A relatively long string " + 
    "- delimited by dashes. - Adjust if necessary " * 100 
delimiter = "-" 

Benchmark.bmbm do |bench| 
    bench.report "collect { |s| s.lstrip.rstrip }" do 
    # Your example. 
    n.times { input.split(delimiter).collect { |s| s.lstrip.rstrip } } 
    end 

    bench.report "collect { |s| s.strip }" do 
    # Use .strip instead of .lstrip.rstrip. 
    n.times { input.split(delimiter).collect { |s| s.strip } } 
    end 

    bench.report "collect { |s| s.strip! }" do 
    # Use .strip! to modifiy strings in-place. 
    n.times { input.split(delimiter).collect { |s| s.strip! } } 
    end 

    bench.report "collect(&:strip!)" do 
    # Slow block creation (&:strip! syntax). 
    n.times { input.split(delimiter).collect(&:strip!) } 
    end 

    bench.report "split(/\\s*\#{delim}\\s*/) (static)" do 
    # Use static regex -- only possible if delimiter doesn't change. 
    re = Regexp.new("\s*#{delimiter}\s*") 
    n.times { input.split(re) } 
    end 

    bench.report "split(/\\s*\#{delim}\\s*/) (dynamic)" do 
    # Use dynamic regex, slower to create every time? 
    n.times { input.split(Regexp.new("\s*#{delimiter}\s*")) } 
    end 
end 

我的筆記本電腦上面列出的參數結果:

         user  system  total  real 
collect { |s| s.lstrip.rstrip } 7.970000 0.050000 8.020000 ( 8.246598) 
collect { |s| s.strip }   6.350000 0.050000 6.400000 ( 6.837892) 
collect { |s| s.strip! }   5.110000 0.020000 5.130000 ( 5.148050) 
collect(&:strip!)     5.700000 0.030000 5.730000 ( 6.010845) 
split(/\s*#{delim}\s*/) (static) 6.890000 0.030000 6.920000 ( 7.071058) 
split(/\s*#{delim}\s*/) (dynamic) 6.900000 0.020000 6.920000 ( 6.983142) 

從上面的我可能會得出結論:

  • 使用的strip代替.lstrip.rstrip更快。
  • 首選&:strip!超過{ |s| s.strip! }帶有性能成本。
  • 簡單的正則表達式幾乎和使用split + strip一樣快。我能想到的,

事情可能影響結果:

  • 分隔符的長度(以及它是否是空白)。
  • 要分割的字符串的長度。
  • 字符串中可拆分塊的長度。

但是不要拿我的話來說。 衡量它!

+0

+1爲例 – Aurril 2010-03-02 22:27:56

+0

這是我收到的最佳答案。支持事實。當然,我也學到了一些基準測試!謝謝。 – ramonrails 2010-03-08 17:22:42

0

我只看到一個優化ommiting

p.lstrip.rstrip 

p.strip! 
+0

你的意思是'p.strip'? – 2010-03-02 21:53:02

+0

p.strip!與p.strip一樣有效。 只需p.strip!是一個更快的勾號,因爲它不需要製作一份p – Aurril 2010-03-02 22:26:10

+1

strip!如果字符串未被更改,則返回nil。如果沒有條件檢查,將無法正確匹配邏輯。 – ramonrails 2010-03-08 17:21:51

1

你可以試試正則表達式:

phrase.strip.split(/\s*#{delimiter}\s*/) 
+1

不要忘了首先''去掉'短語'以擺脫前/後空白。 – 2010-03-03 14:54:51

+0

@glenn:好點! – 2010-03-03 14:56:04

+0

該解決方案不會去除拆分結果中每個元素周圍的空格。 – ramonrails 2010-03-08 17:20:02

相關問題