Bug #5127

ruby 1.9.3 prev1 で Array#[]=( Array.new ) が1.9.2より2倍遅い

Added by Anonymous over 2 years ago. Updated over 2 years ago.

[ruby-dev:44285]
Status:Closed
Priority:Normal
Assignee:Narihiro Nakamura
Category:-
Target version:1.9.3
ruby -v:- Backport:

Description

Arrayオブジェクトを Array#[]= で設定する場合に、
ruby 1.9.3 prev1 が 1.9.2 p290 と比較して2倍ほど遅くなっているようなので
ご報告いたします。

(既知の現象であれば、申し訳ありませんがスルーしてください)


require 'benchmark'

Benchmark.bm(22) do |x|
x.report "Array.new" do
1000000.times do
Array.new(100)
end
end

x.report "Array#[]= with Array" do
a = Array.new(1000000)
1000000.times do |i|
a[i] = Array.new(100)
end
end
end


上記のコードを実行した場合に、私の環境では以下のような結果となります。
$ ruby19 -v bmarray.rb
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86
64-darwin11.0.0]
user system total real
Array.new 0.600000 0.140000 0.740000 ( 0.740639)
Array#[]= with Array 8.590000 0.300000 8.890000 ( 8.874507)

$ ruby -v bmarray.rb
ruby 1.9.3dev (2011-07-31 revision 32789) [x86
64-darwin11.0.0]
user system total real
Array.new 0.670000 0.160000 0.830000 ( 0.826589)
Array#[]= with Array 16.160000 0.280000 16.440000 ( 16.597618)

使用している環境は
- OS : Mac OS X 10.7
- CPU : Intel Core i5
- Memory : 4GB
- compiler: gcc 4.2.1
です。

以上、よろしくお願いいたします。

Associated revisions

Revision 32894
Added by nari over 2 years ago

  • gc.c (gclazysweep): if sweep target slots are not found, we
    try heap_increment() because it might be able to expand the
    heap. [Bug #5127]

  • gc.c (gcclearmarkonsweep_slots): if a sweeping was
    interrupted, we expand the heap if at all possible.

History

#1 Updated by Motohiro KOSAKI over 2 years ago

  • Target version set to 1.9.3

重要な問題だと思いますので、チケット化しました。

#2 Updated by Tomoyuki Chikanaga over 2 years ago

Linux(Ubuntu 10.4 gcc 4.4.3) でも試してみたところやはり倍近く時間がかかっていました。1.9.3 ではなく trunk とですが。

$ ruby-1.9.2 bm_array.rb
user system total real
Array.new 2.340000 0.070000 2.410000 ( 2.427617)
Array#[]= with Array 23.850000 1.220000 25.070000 ( 25.506229)

$ ruby-trunk bm_array.rb
user system total real
Array.new 2.200000 0.930000 3.130000 ( 3.161638)
Array#[]= with Array 44.950000 1.250000 46.200000 ( 46.584050)

ためしに以下のように GC を切ってみるとほぼ同じくらいになりました。ついでに一時オブジェクトの生成数が増えてるんじゃないかと ObjectSpace.each_object の返す数も出してみましたが特に増えていないので、主に GC の影響でしょうか。とりあえずご報告まで。

$ cat bm_array.rb
require 'benchmark'

Benchmark.bm(22) do |x|
GC.disable
x.report "Array.new" do
1000000.times do
Array.new(100)
end
end
puts "objects count = #{ ObjectSpace.eachobject{} }"
GC.enable
GC.start
GC.disable
x.report "Array#[]= with Array" do
a = Array.new(1
000000)
1
000000.times do |i|
a[i] = Array.new(100)
end
end
puts "objects count = #{ ObjectSpace.each
object{} }"
end

$ ruby-1.9.2 bm_array.rb
user system total real
Array.new 1.470000 1.220000 2.690000 ( 2.705700)
objects count = 1007204
Array#[]= with Array 1.910000 0.030000 1.940000 ( 2.055783)
objects count = 1003992

$ ruby-trunk bm_array.rb
user system total real
Array.new 1.510000 1.230000 2.740000 ( 2.753933)
objects count = 1005182
Array#[]= with Array 1.940000 0.010000 1.950000 ( 1.977659)
objects count = 1002551

#3 Updated by Narihiro Nakamura over 2 years ago

  • Assignee set to Narihiro Nakamura

GCの問題のようですので、引き取ります。

#4 Updated by Narihiro Nakamura over 2 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r32894.
, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • gc.c (gclazysweep): if sweep target slots are not found, we
    try heap_increment() because it might be able to expand the
    heap. [Bug #5127]

  • gc.c (gcclearmarkonsweep_slots): if a sweeping was
    interrupted, we expand the heap if at all possible.

Also available in: Atom PDF