关于ruby几种String连接性能的小测试

最近开始学习Ruby. 据说“Performance”对于C++程序员来说,就像骨头对于狗一样。看到Ruby里连接String有几种不同的方式,心里面就好奇哪种最快。写了个测试程序如下:

代码:
require 'benchmark'
include Benchmark

N=100000
EMPTY=""
S="a"*1000
s=""

bm(1) do |x|
    x.report("2-1:") { N.times { S+S } }
    x.report("2-2:") { N.times { "#{S}#{S}" } }
    x.report("2-3:") { N.times { s=""; s<<S<<S } }
    x.report("2-4:") { N.times { s.replace(EMPTY); s<<S<<S } }

    x.report("3-1:") { N.times { S+S+S } }
    x.report("3-2:") { N.times { "#{S}#{S}#{S}" } }
    x.report("3-3:") { N.times { s=""; s<<S<<S<<S } }
    x.report("3-4:") { N.times { s.replace(EMPTY); s<<S<<S<<S } }

    x.report("4-1:") { N.times { S+S+S+S } }
    x.report("4-2:") { N.times { "#{S}#{S}#{S}#{S}" } }
    x.report("4-3:") { N.times { s=""; s<<S<<S<<S<<S } }
    x.report("4-4:") { N.times { s.replace(EMPTY); s<<S<<S<<S<<S } }
end
 
测试结果:
       user     system      total        real
2 - 1 :   1.016000     0.328000     1.344000  (   1.391000 )
2 - 2 :   1.391000     0.422000     1.813000  (   1.812000 )
2 - 3 :   1.562000     0.313000     1.875000  (   1.907000 )
2 - 4 :   1.094000     0.000000     1.094000  (   1.093000 )

3 - 1 :   2.281000     1.015000     3.296000  (   3.313000 )
3 - 2 :   2.516000     0.641000     3.157000  (   3.187000 )
3 - 3 :   2.406000     0.797000     3.203000  (   3.204000 )
3 - 4 :   1.641000     0.000000     1.641000  (   1.640000 )

4 - 1 :   3.859000     1.859000     5.718000  (   5.781000 )
4 - 2 :   2.328000     0.875000     3.203000  (   3.204000 )
4 - 3 :   2.578000     0.813000     3.391000  (   3.437000 )
4 - 4 :   1.906000     0.015000     1.921000  (   1.922000 )

分析:
1)S+S.....+S
      这种方式,实际是调用rb_str_plus(见Ruby 源代码: string.c).而rb_str_plus作的事情主要是:
rb_str_plus(str1, str2)
  malloc memory
, length= str1.length + str2.length
  copy str1 to new memory
  copy str2 to new memory
end

   需要拷贝内存的长度:
   S+S:          2*S.length
   S+S+S:     2*(2*S.length)+S.length= 5*S.length
   S+S+S+S:2*(5*S.length)+S.length= 11*S.length
   ......

2) "#{S}#{S}....#{S}"
      没有找到这种方式的源代码。但是因为测试结果和第三种方式类似,实现方式也应该差不多。我猜测因为第三种方式需要“调用”方法(或者是说发送消息),因而比第二种方式稍慢一点。

3)
s=""; s<<S<<S.....<<S
     
这种方式,实际是调用rb_str_concat(见Ruby 源代码: string.c).而rb_str_concat作的事情主要是:
rb_str_concat(str1, str2)
  realloc memory, length
= str1.length + str2.length + 1
  copy str2 to new memory
end
  
   需要拷贝内存的长度:
   S+S:          1*S.length
   S+S+S:     2*S.length
   S+S+S+S: 3*S.length
   ......

   需要注意的是:
   s="";  每次都会产生一个新的空字符串

4)
s.replace(EMPTY); s<<S<<S<<....S
      
这种方式,和第三种方式基本相同,除了:
       s.replace(EMPTY);   不会每次产生一个新的空字符串。

       有趣的是,在Ruby1.8里,String类没有clear方法。在1.9里面才有:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/189314
  
结论:
 
1)一般而言,第四种方式最快,第一种方式最慢。
 2)避免Ruby分配过多的新String,可以较明显的提高性能。
 3)在性能不是特别重要的情况下,第二种方式最好,因为一般比第一种快,而且只需要一条语句。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值