aboutsummaryrefslogtreecommitdiffstats
path: root/array.c
diff options
context:
space:
mode:
authorwatson1978 <watson1978@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-24 06:57:08 +0000
committerwatson1978 <watson1978@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-05-24 06:57:08 +0000
commit53c88c6d79993da468c48f62e7402fdb980c1002 (patch)
tree41810a35a0aa787ca77253e4afd526c48c6b2c11 /array.c
parenta800231e9d9220f39513a427ee30b5d5a02f7c05 (diff)
downloadruby-53c88c6d79993da468c48f62e7402fdb980c1002.tar.gz
Improve performance in where push the element into non shared Array object
* array.c (ary_ensure_room_for_push): use rb_ary_modify_check() instead of rb_ary_modify() to check whether the object can be modified for non shared Array object. rb_ary_modify() has the codes for shared Array object too. In here, it has condition branch for shared / non shared Array object and it can use rb_ary_modify_check() which is smaller function than rb_ary_modify() for non shared object. rb_ary_modify_check() will be expand as inline function. If it will compile with GCC, Array#<< will be faster around 8%. [ruby-core:81082] [Bug #13553] [Fix GH-1609] ## Clang 802.0.42 ### Before Array#<< 9.353M (± 1.7%) i/s - 46.787M in 5.004123s Array#push 7.702M (± 1.1%) i/s - 38.577M in 5.009338s Array#values_at 6.133M (± 1.9%) i/s - 30.699M in 5.007772s ### After Array#<< 9.458M (± 2.0%) i/s - 47.357M in 5.009069s Array#push 7.921M (± 1.8%) i/s - 39.665M in 5.009151s Array#values_at 6.377M (± 2.3%) i/s - 31.881M in 5.001888s ### Result Array#<< -> 1.2% faster Array#push -> 2.8% faster Array#values_at -> 3.9% faster ## GCC 7.1.0 ### Before Array#<< 10.497M (± 1.1%) i/s - 52.665M in 5.017601s Array#push 8.527M (± 1.6%) i/s - 42.777M in 5.018003s Array#values_at 7.621M (± 1.7%) i/s - 38.152M in 5.007910s ### After Array#<< 11.403M (± 1.3%) i/s - 57.028M in 5.001849s Array#push 8.924M (± 1.3%) i/s - 44.609M in 4.999940s Array#values_at 8.291M (± 1.4%) i/s - 41.487M in 5.004727s ### Result Array#<< -> 8.3% faster Array#push -> 4.3% faster Array#values_at -> 8.7% faster ## Test code require 'benchmark/ips' Benchmark.ips do |x| x.report "Array#<<" do |i| i.times { [1,2] << 3 } end x.report "Array#push" do |i| i.times { [1,2].push(3) } end x.report "Array#values_at" do |i| ary = [1, 2, 3, 4, 5] i.times { ary.values_at(0, 2, 4) } end end git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58867 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r--array.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/array.c b/array.c
index 0775e82999..6d7838b9d3 100644
--- a/array.c
+++ b/array.c
@@ -380,8 +380,11 @@ ary_ensure_room_for_push(VALUE ary, long add_len)
}
}
}
+ rb_ary_modify(ary);
+ }
+ else {
+ rb_ary_modify_check(ary);
}
- rb_ary_modify(ary);
capa = ARY_CAPA(ary);
if (new_len > capa) {
ary_double_capa(ary, new_len);