代码之家  ›  专栏  ›  技术社区  ›  Ram on Rails

ruby:optimize=>phrase.split(分隔符).collect{p p.lstrip.rstrip}

  •  4
  • Ram on Rails  · 技术社区  · 15 年前

    ruby:最优化的表达式是什么呢?

    phrase.split(delimiter).collect {|p| p.lstrip.rstrip }
    
    3 回复  |  直到 15 年前
        1
  •  10
  •   molf    15 年前

    为清晰起见,我更喜欢以下内容:

    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 + .

    我能想到的事情可能会影响结果:

    • 分隔符的长度(以及是否为空白)。
    • 要拆分的字符串的长度。
    • 字符串中可拆分块的长度。

    但别相信我的话。 测量它!

        2
  •  1
  •   Mark Byers    15 年前

    可以尝试使用正则表达式:

    phrase.strip.split(/\s*#{delimiter}\s*/)
    
        3
  •  0
  •   Aurril Thorbjørn Ravn Andersen    15 年前

    我只看到操作上的优化

    p.lstrip.rstrip
    

    具有

    p.strip!