Ruby - Array.join与String Concatenation(效率)

exi*_*uio 20 ruby

我记得曾经一度骂过用Python连接字符串.有人告诉我,在Python中创建一个字符串列表并在以后加入它们会更有效.我把这种做法带到了JavaScript和Ruby中,虽然我不确定它在后者中是否具有相同的好处.

任何人都可以告诉我,加入一个字符串数组并调用它是否更有效(资源和执行):加入它们或者根据需要在Ruby编程语言中连接一个字符串?

谢谢.

jer*_*son 31

使用Benchmark类自己尝试一下.

require "benchmark"

n = 1000000
Benchmark.bmbm do |x|
  x.report("concatenation") do
    foo = ""
    n.times do
      foo << "foobar"
    end
  end

  x.report("using lists") do
    foo = []
    n.times do
      foo << "foobar"
    end
    string = foo.join
  end
end
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

Rehearsal -------------------------------------------------
concatenation   0.300000   0.010000   0.310000 (  0.317457)
using lists     0.380000   0.050000   0.430000 (  0.442691)
---------------------------------------- total: 0.740000sec

                    user     system      total        real
concatenation   0.260000   0.010000   0.270000 (  0.309520)
using lists     0.310000   0.020000   0.330000 (  0.363102)
Run Code Online (Sandbox Code Playgroud)

所以看起来在这种情况下连接速度要快一些.根据您的用例对您的系统进行基准测试.

  • +1基准!基准!基准!Benchmark是我们的朋友!:-) (6认同)
  • 它可能在不同的环境,不同的数据大小以及不同版本的Ruby中有所不同.基准测试和优化有时可能是黑魔法. (3认同)

Mla*_*vić 8

有趣,基准测试给出了令人惊讶的结果(除非我做错了):

require 'benchmark'

N = 1_000_000
Benchmark.bm(20) do |rep|

  rep.report('+') do
    N.times do
      res = 'foo' + 'bar' + 'baz'
    end
  end

  rep.report('join') do
    N.times do
      res = ['foo', 'bar', 'baz'].join
    end
  end

  rep.report('<<') do
    N.times do
      res = 'foo' << 'bar' << 'baz'
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

jablan@poneti:~/dev/rb$ ruby concat.rb 
                          user     system      total        real
+                     1.760000   0.000000   1.760000 (  1.791334)
join                  2.410000   0.000000   2.410000 (  2.412974)
<<                    1.380000   0.000000   1.380000 (  1.376663)
Run Code Online (Sandbox Code Playgroud)

join原来是最慢的.它可能与创建数组有关,但这就是你必须要做的事情.

哦BTW,

jablan@poneti:~/dev/rb$ ruby -v
ruby 1.9.1p378 (2010-01-10 revision 26273) [i486-linux]
Run Code Online (Sandbox Code Playgroud)

  • 我认为差异可能是由于您在循环中创建了大量的小型数组,而不是在数组之外构建了一个长字符串。您的基准测试和上面的测试正在测试不同的方案。 (2认同)