[Groonga-commit] droonga/fluent-plugin-droonga at 1e5b5a1 [master] Simplify

Back to archive index

Kouhei Sutou kou****@clear*****
Tue Mar 18 11:52:32 JST 2014


In <53279EF8.9060400 �� clear-code.com>
  "Re: [Groonga-commit] droonga/fluent-plugin-droonga �� 1e5b5a1 [master] Simplify" on Tue, 18 Mar 2014 10:18:48 +0900,
  Kenji Okimoto <okimoto �� clear-code.com> wrote:

> 配列への要素の追加で、速度を求めるなら + よりも << か push を使った方がいいと思います。
> # 配列ではなかったら、すみません。。。

配列です!
今回のケースでは+が妥当だと思っています。

以下、理由です。

実は、ここでは、破壊的に元のオブジェクトを変えてはいけないと
いう制約があります。で、<</pushは破壊的なのでそのままでは使
えません。使うなら事前にコピーしておく必要があります。
で、そのために、Marshal.load(Marshal.dump({...}))をしていた
のですが、そもそもこれが重いのでdupに変えたという経緯があり
ます。

> $ cat a.rb
> require "benchmark"
> 
> a = []
> b = []
> c = []
> 
> Benchmark.bmbm do |x|
>    x.report("+"){ 100000.times{|n| a += [n] }}
>    x.report("push"){ 100000.times{|n| b.push(n) }}
>    x.report("<<"){100000.times{|n| c << n } }
> end
> 
> $ ruby a.rb
> Rehearsal ----------------------------------------
> +      7.880000   1.530000   9.410000 (  9.412625)
> push   0.010000   0.000000   0.010000 (  0.008801)
> <<     0.000000   0.000000   0.000000 (  0.006635)
> ------------------------------- total: 9.420000sec
> 
>             user     system      total        real
> +     36.050000   8.680000  44.730000 ( 44.744900)
> push   0.010000   0.000000   0.010000 (  0.008950)
> <<     0.010000   0.000000   0.010000 (  0.006551)

ベンチマークがあると話が早くていいですね!

実際は100000回も繰り返すことがなく、せいぜい数回くらいです。
ということで、次のベンチマークの方が今回のケースによりマッチ
しています。

--
require "benchmark"

a = []
b = []
c = []

GC.disable
# N=100000
N=10
Benchmark.bmbm do |x|
   x.report("+"){ N.times{|n| a += [n] }}
   x.report("push"){ N.times{|n| b.push(n) }}
   x.report("<<"){N.times{|n| c << n } }
end
--

で、結果はこうなります。

--
Rehearsal ----------------------------------------
+      0.000000   0.000000   0.000000 (  0.000007)
push   0.000000   0.000000   0.000000 (  0.000005)
<<     0.000000   0.000000   0.000000 (  0.000004)
------------------------------- total: 0.000000sec

           user     system      total        real
+      0.000000   0.000000   0.000000 (  0.000005)
push   0.000000   0.000000   0.000000 (  0.000003)
<<     0.000000   0.000000   0.000000 (  0.000003)
--

たしかに+の方が重いですが、このくらいならアプリケーションか
らみたら誤差ですし、Marshal.load(Marshal.dump())がなくせるの
で、トータルでは+に割にあうといえます。


ということで、ここのコードは+で妥当であると思っています!

コメントありがとうございましたー




More information about the Groonga-commit mailing list
Back to archive index