2017-03-14 38 views
1

通常需要连接字符串,而在Ruby中我们有这样做的常用方法:将字符串追加,连接和插入另一个字符串,或者使用String中内置的concat方法。 (我们这样做是为了灵活性和简化从其他语言到Ruby过渡的多种方式。)如何在Ruby中快速连接两个字符串

与开始:

'a ' << 'z'  # => "a z" 
'a '.concat('z') # => "a z" 
'a ' + 'z'  # => "a z" 
"a #{'z'}"  # => "a z" 

假设我们不想改变任何字符串和字符串不会被分配给变量,加入它们的最快方式是什么,并且随着“左”字符串的大小增长,最快的方式会改变吗?

对于那些不知道为什么我们会发布这样的问题的人,这是为了帮助教育和展示执行特定任务的最有效方式。在这种情况下,Ruby的新手往往会拖延旧的方式来处理它们,并且无意中编写的代码运行速度超过了必要的速度。对他们的编码风格进行简单的更改可以使代码更快。

+5

我假设你已经准备好了基准测试结果,并且很快就会发布。 :) –

+0

让我来帮你,https://coderwall.com/p/ac5j9g/或--concat-what-is-faster-for-appending-string-in-ruby –

+0

@DeepakMahakale'.concat'变异左字符串,但。 –

回答

4

与短字符串开始:

z = 'z' 
'a ' << z  # => "a z" 
'a '.concat(z) # => "a z" 
'a ' + z  # => "a z" 
"a #{z}"  # => "a z" 

require 'fruity' 
compare do 
    append  { 'a ' << z} 
    concat  { 'a '.concat(z)} 
    plus  { 'a ' + z} 
    interpolate { "a #{z}" } 
end 

# >> Running each test 65536 times. Test will take about 2 seconds. 
# >> interpolate is similar to append 
# >> append is similar to plus 
# >> plus is faster than concat by 2x ± 0.1 

增加了 “左” 的字符串为11个字符:

require 'fruity' 
compare do 
    append  { 'abcdefghij ' << z} 
    concat  { 'abcdefghij '.concat(z)} 
    plus  { 'abcdefghij ' + z} 
    interpolate { "abcdefghij #{z}" } 
end 

# >> Running each test 65536 times. Test will take about 2 seconds. 
# >> interpolate is similar to append 
# >> append is similar to plus 
# >> plus is faster than concat by 2x ± 1.0 

51个字符:

compare do 
    append  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' << z} 
    concat  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij '.concat(z)} 
    plus  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' + z} 
    interpolate { "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij #{z}" } 
end 

# >> Running each test 32768 times. Test will take about 2 seconds. 
# >> plus is faster than append by 2x ± 1.0 
# >> append is similar to interpolate 
# >> interpolate is similar to concat 

101:

compare do 
    append  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' << z} 
    concat  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij '.concat(z)} 
    plus  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' + z} 
    interpolate { "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij #{z}" } 
end 

# >> Running each test 32768 times. Test will take about 2 seconds. 
# >> plus is faster than interpolate by 2x ± 0.1 
# >> interpolate is similar to append 
# >> append is similar to concat 

501:

compare do 
    append  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' << z} 
    concat  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij '.concat(z)} 
    plus  { 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij ' + z} 
    interpolate { "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij #{z}" } 
end 

# >> Running each test 16384 times. Test will take about 1 second. 
# >> plus is faster than append by 2x ± 0.1 
# >> append is similar to interpolate 
# >> interpolate is similar to concat 

一旦串了过去50个字符+的表现一直超过其他人。

在评论中提到了其中一些突变字符串在左边。下面是如果它是在左边,而不是一个文字字符串变量会发生什么:相比

a = 'a' 
z = 'z' 

a << z # => "az" 
a # => "az" 

a = 'a' 
a.concat(z) # => "az" 
a # => "az" 

a + z # => "az" 
a  # => "a" 

"#{a} #{z}" # => "a z" 
a   # => "a" 

注意:在使用答案的最初版本有一个坏的测试:

"a #{'z'}" 

有这个问题是Ruby是足够聪明的认识到,'z'是另一种文字和字符串转换为:

"a z" 

最终结果是测试会比其他测试更不公平。

+0

这是一个wiki,所以如果你知道你在做什么,并且想要改善它,那么你可以免费。如果你不知道,并且你改变了它,它会被回滚。 –

+2

你的'interpolate'不是真正的插值,因为'“z#{”z“}”'将被编译成“z z”'。要在这里做真正的基准,你必须引入附加变量'interpolate {z ='z'; “a#{z}”}' – fl00r

+0

好点。固定。 –