(本文数据较多,在rss reader里面可能可读性不是很好,可考虑直接在线阅读) 昨天看到pipitu的这篇blog,觉得蛮有意思,文章比较了python和java的list performance,只可惜没有include ruby 1.8和ruby 1.9,不然结论会更有悬念一点,呵呵. 由于无法营造一致的软硬件环境,也不愿意重复pipitu关于python和java部分的工作,这里就只好先简单benchmark(如果可以算是的话)一下ruby 1.8和1.9里的list (array) performance了,也许pipitu以后有空更新include ruby也说不定:) 先看一下我们用的ruby的版本: [cc lang=”bash”] $ ruby -v ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9] [/cc] [cc lang=”bash”] $ ruby1.9 -v ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-darwin9] [/cc] 还有os: [cc lang=”bash” nowrap=”false”] $ uname -a Darwin macbook.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 [/cc] benchmark的方法和pipitu的python sample类似,就是往空的list里面循环n次append,由于循环也被引入,其performance也值得考虑,因为众所周知ruby里面做一件事犹如孔乙己的茴字写法一样有n种办法,其performance也各不一样,说不定pipitu以后会和python, java进行横向,咱还是挑相对快一点的好~ 不过话说回来,再怎么的精挑细选,java那边还是基本没有悬念,真正有悬念的,我们都心知肚明,呵呵。 所以真正运动之前先来点热身运动,看看哪个循环在我这相对要快: [cc lang=”ruby”] require ‘benchmark’ n = ARGV.empty? ? 10 6 : 10 ARGV[0].to_i puts “n=#{n}” Benchmark.bmbm do |b| b.report(“for:”) { for i in 1..n ; a = “0”; end } b.report(“times:”) { n.times do ; a = “0”; end } b.report(“upto:”) { 1.upto(n) do ; a = “0”; end } b.report(“downto:”) { n.downto(1) do ; a = “0”; end } end [/cc] 以上是我所想到的比较常见的4种茴字写法,程序默认取n=10^6进行循环,也可以接受一个作为幂指数的命令行参数,Benchmark的bmbm方法会先dry run一遍所有test作为rehearsal,等memory和garbage collection的状态相对stable了以后才进行真正的benchmark,这样先运行和后运行的report会相对公平一点。 默认运行( n=10^6 )的结果如下: [cc lang=”bash”] n=1000000 Rehearsal ——————————————- for: 0.310000 0.000000 0.310000 ( 0.313392) times: 0.290000 0.000000 0.290000 ( 0.297268) upto: 0.300000 0.000000 0.300000 ( 0.300311) downto: 0.310000 0.000000 0.310000 ( 0.304146) ———————————- total: 1.210000sec user system total real for: 0.310000 0.000000 0.310000 ( 0.313129) times: 0.290000 0.000000 0.290000 ( 0.297470) upto: 0.300000 0.000000 0.300000 ( 0.302154) downto: 0.310000 0.000000 0.310000 ( 0.305562) [/cc] 一次完整运行( n=10~10^8 )的数据结果如下: [cc lang=”bash”] n=10 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.000018) times: 0.000000 0.000000 0.000000 ( 0.000011) upto: 0.000000 0.000000 0.000000 ( 0.000047) downto: 0.000000 0.000000 0.000000 ( 0.000053) ———————————- total: 0.000000sec user system total real for: 0.000000 0.000000 0.000000 ( 0.000014) times: 0.000000 0.000000 0.000000 ( 0.000011) upto: 0.000000 0.000000 0.000000 ( 0.000011) downto: 0.000000 0.000000 0.000000 ( 0.000011) ===================================================== n=100 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.000041) times: 0.000000 0.000000 0.000000 ( 0.000031) upto: 0.000000 0.000000 0.000000 ( 0.000033) downto: 0.000000 0.000000 0.000000 ( 0.000040) ———————————- total: 0.000000sec user system total real for: 0.000000 0.000000 0.000000 ( 0.000035) times: 0.000000 0.000000 0.000000 ( 0.000030) upto: 0.000000 0.000000 0.000000 ( 0.000031) downto: 0.000000 0.000000 0.000000 ( 0.000031) ===================================================== n=1000 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.000367) times: 0.000000 0.000000 0.000000 ( 0.000315) upto: 0.000000 0.000000 0.000000 ( 0.000319) downto: 0.000000 0.000000 0.000000 ( 0.000854) ———————————- total: 0.000000sec user system total real for: 0.000000 0.000000 0.000000 ( 0.000273) times: 0.000000 0.000000 0.000000 ( 0.000250) upto: 0.000000 0.000000 0.000000 ( 0.000254) downto: 0.000000 0.000000 0.000000 ( 0.000258) ===================================================== n=10000 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.003388) times: 0.010000 0.000000 0.010000 ( 0.003056) upto: 0.000000 0.000000 0.000000 ( 0.003006) downto: 0.000000 0.000000 0.000000 ( 0.003084) ———————————- total: 0.010000sec user system total real for: 0.010000 0.000000 0.010000 ( 0.003114) times: 0.000000 0.000000 0.000000 ( 0.002955) upto: 0.000000 0.000000 0.000000 ( 0.003047) downto: 0.010000 0.000000 0.010000 ( 0.004650) ===================================================== n=100000 Rehearsal ——————————————- for: 0.030000 0.000000 0.030000 ( 0.032892) times: 0.030000 0.000000 0.030000 ( 0.029808) upto: 0.030000 0.000000 0.030000 ( 0.031190) downto: 0.030000 0.000000 0.030000 ( 0.030379) ———————————- total: 0.120000sec user system total real for: 0.030000 0.000000 0.030000 ( 0.033382) times: 0.030000 0.000000 0.030000 ( 0.029139) upto: 0.030000 0.000000 0.030000 ( 0.031608) downto: 0.030000 0.000000 0.030000 ( 0.030498) ===================================================== n=1000000 Rehearsal ——————————————- for: 0.310000 0.000000 0.310000 ( 0.313392) times: 0.290000 0.000000 0.290000 ( 0.297268) upto: 0.300000 0.000000 0.300000 ( 0.300311) downto: 0.310000 0.000000 0.310000 ( 0.304146) ———————————- total: 1.210000sec user system total real for: 0.310000 0.000000 0.310000 ( 0.313129) times: 0.290000 0.000000 0.290000 ( 0.297470) upto: 0.300000 0.000000 0.300000 ( 0.302154) downto: 0.310000 0.000000 0.310000 ( 0.305562) ===================================================== n=10000000 Rehearsal ——————————————- for: 3.090000 0.000000 3.090000 ( 3.109693) times: 2.940000 0.010000 2.950000 ( 2.946662) upto: 2.990000 0.010000 3.000000 ( 3.003812) downto: 3.010000 0.000000 3.010000 ( 3.021900) ——————————— total: 12.050000sec user system total real for: 3.110000 0.010000 3.120000 ( 3.119928) times: 2.950000 0.010000 2.960000 ( 2.992141) upto: 3.000000 0.010000 3.010000 ( 3.044853) downto: 3.020000 0.000000 3.020000 ( 3.036987) ===================================================== n=100000000 Rehearsal ——————————————- for: 30.950000 0.070000 31.020000 ( 31.139756) times: 29.360000 0.060000 29.420000 ( 29.543839) upto: 29.890000 0.070000 29.960000 ( 30.102346) downto: 30.080000 0.070000 30.150000 ( 30.271642) ——————————– total: 120.550000sec user system total real for: 31.130000 0.080000 31.210000 ( 31.359814) times: 29.420000 0.050000 29.470000 ( 29.630556) upto: 30.050000 0.060000 30.110000 ( 30.197589) downto: 30.180000 0.050000 30.230000 ( 30.361343) ===================================================== [/cc] 由于精力有限,就不做多次运行取平均值这种相对无聊的事情了,结果虽然不严谨也无法真正判断出究竟谁最快(times和upto,downto是在伯仲之间),但至少可以看出for in range是相对最慢的。 换ruby1.9后的运行结果与上基本一致,详细数据如下: [cc lang=”bash”] n=10 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.000029) times: 0.000000 0.000000 0.000000 ( 0.000050) upto: 0.000000 0.000000 0.000000 ( 0.000014) downto: 0.000000 0.000000 0.000000 ( 0.000013) ———————————- total: 0.000000sec user system total real for: 0.000000 0.000000 0.000000 ( 0.000014) times: 0.000000 0.000000 0.000000 ( 0.000011) upto: 0.000000 0.000000 0.000000 ( 0.000012) downto: 0.000000 0.000000 0.000000 ( 0.000012) ===================================================== n=100 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.000061) times: 0.000000 0.000000 0.000000 ( 0.000103) upto: 0.000000 0.000000 0.000000 ( 0.000078) downto: 0.000000 0.000000 0.000000 ( 0.000060) ———————————- total: 0.000000sec user system total real for: 0.000000 0.000000 0.000000 ( 0.000066) times: 0.000000 0.000000 0.000000 ( 0.000061) upto: 0.000000 0.000000 0.000000 ( 0.000061) downto: 0.000000 0.000000 0.000000 ( 0.000061) ===================================================== n=1000 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.000465) times: 0.000000 0.000000 0.000000 ( 0.000461) upto: 0.000000 0.000000 0.000000 ( 0.000477) downto: 0.000000 0.000000 0.000000 ( 0.000428) ———————————- total: 0.000000sec user system total real for: 0.000000 0.000000 0.000000 ( 0.000388) times: 0.000000 0.000000 0.000000 ( 0.000339) upto: 0.000000 0.000000 0.000000 ( 0.000341) downto: 0.000000 0.000000 0.000000 ( 0.000339) ===================================================== n=10000 Rehearsal ——————————————- for: 0.000000 0.000000 0.000000 ( 0.004486) times: 0.010000 0.000000 0.010000 ( 0.003675) upto: 0.000000 0.000000 0.000000 ( 0.004407) downto: 0.000000 0.000000 0.000000 ( 0.004121) ———————————- total: 0.010000sec user system total real for: 0.010000 0.000000 0.010000 ( 0.003961) times: 0.000000 0.000000 0.000000 ( 0.005113) upto: 0.010000 0.000000 0.010000 ( 0.003592) downto: 0.000000 0.000000 0.000000 ( 0.003592) ===================================================== n=100000 Rehearsal ——————————————- for: 0.040000 0.000000 0.040000 ( 0.042573) times: 0.030000 0.000000 0.030000 ( 0.039094) upto: 0.030000 0.000000 0.030000 ( 0.041495) downto: 0.040000 0.000000 0.040000 ( 0.049316) ———————————- total: 0.140000sec user system total real for: 0.040000 0.000000 0.040000 ( 0.040422) times: 0.040000 0.000000 0.040000 ( 0.037030) upto: 0.040000 0.000000 0.040000 ( 0.041921) downto: 0.040000 0.000000 0.040000 ( 0.039868) ===================================================== n=1000000 Rehearsal ——————————————- for: 0.390000 0.000000 0.390000 ( 0.401887) times: 0.370000 0.000000 0.370000 ( 0.376656) upto: 0.370000 0.010000 0.380000 ( 0.384750) downto: 0.370000 0.000000 0.370000 ( 0.380184) ———————————- total: 1.510000sec user system total real for: 0.400000 0.000000 0.400000 ( 0.411929) times: 0.370000 0.000000 0.370000 ( 0.386443) upto: 0.370000 0.010000 0.380000 ( 0.379820) downto: 0.370000 0.000000 0.370000 ( 0.379068) ===================================================== n=10000000 Rehearsal ——————————————- for: 3.920000 0.020000 3.940000 ( 4.021434) times: 3.690000 0.030000 3.720000 ( 3.844118) upto: 3.710000 0.030000 3.740000 ( 3.844035) downto: 3.700000 0.020000 3.720000 ( 3.795330) ——————————— total: 15.120000sec user system total real for: 3.910000 0.020000 3.930000 ( 4.003016) times: 3.670000 0.020000 3.690000 ( 3.749495) upto: 3.700000 0.020000 3.720000 ( 3.919785) downto: 3.690000 0.030000 3.720000 ( 3.789975) ===================================================== n=100000000 Rehearsal ——————————————- for: 39.260000 0.240000 39.500000 ( 40.293460) times: 36.700000 0.210000 36.910000 ( 37.450910) upto: 37.020000 0.260000 37.280000 ( 38.963391) downto: 36.940000 0.230000 37.170000 ( 37.806189) ——————————– total: 150.860000sec user system total real for: 39.230000 0.240000 39.470000 ( 40.471694) times: 36.850000 0.240000 37.090000 ( 38.302817) upto: 36.870000 0.230000 37.100000 ( 37.802815) downto: 36.970000 0.220000 37.190000 ( 38.052300) ===================================================== [/cc] 有趣的是ruby1.9的循环操作性能竟然普遍都是负增长,这倒为我们之后的list performance比较埋下了伏笔。 热身运动到此结束,似乎有喧宾夺主之嫌,所以赶紧搞个part 2…,下篇文章我们会用上面循环性能测试的疑似最佳表现者times来进行list append性能测试,敬请期待。