irb(main):001:0> s = 'a'
=> "a"
irb(main):002:0> s + 'b'
=> "ab"
irb(main):003:0> s
=> "a"
irb(main):004:0> s << 'b'
=> "ab"
irb(main):005:0> s
=> "ab"
require 'benchmark'
N = 1000
BASIC_LENGTH = 10
5.times do |factor|
length = BASIC_LENGTH * (10 ** factor)
puts "_" * 60 + "\nLENGTH: #{length}"
Benchmark.bm(10, '+= VS <<') do |x|
concat_report = x.report("+=") do
str1 = ""
str2 = "s" * length
N.times { str1 += str2 }
end
modify_report = x.report("<<") do
str1 = "s"
str2 = "s" * length
N.times { str1 << str2 }
end
[concat_report / modify_report]
end
end
输出:
____________________________________________________________
LENGTH: 10
user system total real
+= 0.000000 0.000000 0.000000 ( 0.004671)
<< 0.000000 0.000000 0.000000 ( 0.000176)
+= VS << NaN NaN NaN ( 26.508796)
____________________________________________________________
LENGTH: 100
user system total real
+= 0.020000 0.000000 0.020000 ( 0.022995)
<< 0.000000 0.000000 0.000000 ( 0.000226)
+= VS << Inf NaN NaN (101.845829)
____________________________________________________________
LENGTH: 1000
user system total real
+= 0.270000 0.120000 0.390000 ( 0.390888)
<< 0.000000 0.000000 0.000000 ( 0.001730)
+= VS << Inf Inf NaN (225.920077)
____________________________________________________________
LENGTH: 10000
user system total real
+= 3.660000 1.570000 5.230000 ( 5.233861)
<< 0.000000 0.010000 0.010000 ( 0.015099)
+= VS << Inf 157.000000 NaN (346.629692)
____________________________________________________________
LENGTH: 100000
user system total real
+= 31.270000 16.990000 48.260000 ( 48.328511)
<< 0.050000 0.050000 0.100000 ( 0.105993)
+= VS << 625.400000 339.800000 NaN (455.961373)
11 回答
您可以通过以下几种方式实现:
正如您使用
<<
所示,但这不是通常的方法使用字符串插值
+
第二种方法在内存/速度方面似乎比我看到的更有效(虽然没有测量) . 当ROOT_DIR为零时,所有三种方法都会抛出未初始化的常量错误 .
处理路径名时,您可能希望使用
File.join
以避免弄乱路径名分隔符 .最后,这是一个品味问题 .
+
运算符是正常的连接选择,可能是连接字符串的最快方法 .+
和<<
之间的区别在于<<
更改了左侧的对象,而+
则没有 .如果您只是连接路径,则可以使用Ruby自己的File.join方法 .
来自http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/
使用
<<
akaconcat
远比+=
更有效,因为后者创建一个时态对象并用新对象覆盖第一个对象 .输出:
由于这是一条路径,我可能会使用数组和连接:
这是另一个受this gist启发的基准测试 . 它比较动态和预定义字符串的连接(
+
),追加(<<
)和插值(#{}
) .输出:
结论:MRI中的插值很重 .
我更喜欢使用路径名:
关于来自ruby docs的
<<
和+
:+
:返回包含与str连接的other_str的 new 字符串<<
:将给定对象连接到str . 如果对象是0到255之间的Fixnum,则在连接之前将其转换为字符 .这样的区别是什么变成第一个操作数(
<<
使得在发生的变化,+
返回新的字符串,它是内存较重),将是什么,如果第一个操作数是Fixnum对象(<<
将增加,如果它是字符的代码等于该数字,+
会引发错误)让我向你展示我的所有经验 .
我有一个返回32k记录的查询,对于每个记录,我调用一种方法将该数据库记录格式化为格式化字符串,然后将其连接成一个字符串,在所有这个过程结束时将转换为磁盘中的文件 .
我的问题是,据记录,大约24k,连接字符串的过程导致痛苦 .
我是用常规''运算符做的 .
当我改为'<<'时就像魔术一样 . 真的很快 .
所以,我记得我的旧时代 - 有点像1998年 - 当我使用Java并使用''连接String并从String更改为StringBuffer时(现在我们Java开发人员拥有StringBuilder) .
我相信Ruby世界中的/ <<进程与Java世界中的/ StringBuilder.append相同 .
第一个在内存中重新分配整个对象,另一个只是指向一个新地址 .
连说你说?那么
#concat
方法怎么样?平心而论,
concat
被别名为<<
.以下是更多方法:
等等 ...
您可以使用
+
或<<
运算符,但在ruby.concat
函数中是最优选的函数,因为它比其他运算符快得多 . 你可以像使用它一样 .