diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-29 07:43:22 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-29 07:43:22 +0000 |
commit | 9bc73cd81f29ab9d8fb6e7bbae0322110ecd3faa (patch) | |
tree | f12916c712e112936e1ac5a25321193ab72b95bd /spec/ruby/core/array | |
parent | ff6573b696dc458965c9a93afd9edfaac7d733d4 (diff) | |
download | ruby-9bc73cd81f29ab9d8fb6e7bbae0322110ecd3faa.tar.gz |
array.c: improve operations on small arrays
[Feature #13884]
Reduce number of memory allocations for "and", "or" and "diff"
operations on small arrays
Very often, arrays are used to filter parameters and to select
interesting items from 2 collections and very often these
collections are small enough, for example:
```ruby
SAFE_COLUMNS = [:id, :title, :created_at]
def columns
@all_columns & SAFE_COLUMNS
end
```
In this patch, I got rid of unnecessary memory allocations for
small arrays when "and", "or" and "diff" operations are performed.
name | HEAD | PATCH
-----------------+------:+------:
array_small_and | 0.615 | 0.263
array_small_diff | 0.676 | 0.282
array_small_or | 0.953 | 0.463
name | PATCH
-----------------+------:
array_small_and | 2.343
array_small_diff | 2.392
array_small_or | 2.056
name | HEAD | PATCH
-----------------+------:+------:
array_small_and | 1.429 | 1.005
array_small_diff | 1.493 | 0.878
array_small_or | 1.672 | 1.152
name | PATCH
-----------------+------:
array_small_and | 1.422
array_small_diff | 1.700
array_small_or | 1.452
Author: Dmitry Bochkarev <dimabochkarev@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60057 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/ruby/core/array')
-rw-r--r-- | spec/ruby/core/array/intersection_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/core/array/minus_spec.rb | 10 | ||||
-rw-r--r-- | spec/ruby/core/array/union_spec.rb | 10 |
3 files changed, 16 insertions, 15 deletions
diff --git a/spec/ruby/core/array/intersection_spec.rb b/spec/ruby/core/array/intersection_spec.rb index 9eabe590d9..4d6c2a12d3 100644 --- a/spec/ruby/core/array/intersection_spec.rb +++ b/spec/ruby/core/array/intersection_spec.rb @@ -49,17 +49,18 @@ describe "Array#&" do obj1 = mock('1') obj2 = mock('2') - obj1.should_receive(:hash).at_least(1).and_return(0) - obj2.should_receive(:hash).at_least(1).and_return(0) + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) obj1.should_receive(:eql?).at_least(1).and_return(true) + obj2.should_receive(:eql?).at_least(1).and_return(true) ([obj1] & [obj2]).should == [obj1] ([obj1, obj1, obj2, obj2] & [obj2]).should == [obj1] obj1 = mock('3') obj2 = mock('4') - obj1.should_receive(:hash).at_least(1).and_return(0) - obj2.should_receive(:hash).at_least(1).and_return(0) + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) obj1.should_receive(:eql?).at_least(1).and_return(false) ([obj1] & [obj2]).should == [] @@ -78,7 +79,7 @@ describe "Array#&" do it "properly handles an identical item even when its #eql? isn't reflexive" do x = mock('x') - x.should_receive(:hash).at_least(1).and_return(42) + x.stub!(:hash).and_return(42) x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI. ([x] & [x]).should == [x] diff --git a/spec/ruby/core/array/minus_spec.rb b/spec/ruby/core/array/minus_spec.rb index 5ef90385eb..ffb8d7db06 100644 --- a/spec/ruby/core/array/minus_spec.rb +++ b/spec/ruby/core/array/minus_spec.rb @@ -46,8 +46,8 @@ describe "Array#-" do it "removes an item identified as equivalent via #hash and #eql?" do obj1 = mock('1') obj2 = mock('2') - obj1.should_receive(:hash).at_least(1).and_return(0) - obj2.should_receive(:hash).at_least(1).and_return(0) + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) obj1.should_receive(:eql?).at_least(1).and_return(true) ([obj1] - [obj2]).should == [] @@ -57,8 +57,8 @@ describe "Array#-" do it "doesn't remove an item with the same hash but not #eql?" do obj1 = mock('1') obj2 = mock('2') - obj1.should_receive(:hash).at_least(1).and_return(0) - obj2.should_receive(:hash).at_least(1).and_return(0) + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) obj1.should_receive(:eql?).at_least(1).and_return(false) ([obj1] - [obj2]).should == [obj1] @@ -67,7 +67,7 @@ describe "Array#-" do it "removes an identical item even when its #eql? isn't reflexive" do x = mock('x') - x.should_receive(:hash).at_least(1).and_return(42) + x.stub!(:hash).and_return(42) x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI. ([x] - [x]).should == [] diff --git a/spec/ruby/core/array/union_spec.rb b/spec/ruby/core/array/union_spec.rb index f7fd5c43ac..58fe23448d 100644 --- a/spec/ruby/core/array/union_spec.rb +++ b/spec/ruby/core/array/union_spec.rb @@ -45,8 +45,8 @@ describe "Array#|" do obj1 = mock('1') obj2 = mock('2') - obj1.should_receive(:hash).at_least(1).and_return(0) - obj2.should_receive(:hash).at_least(1).and_return(0) + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) obj2.should_receive(:eql?).at_least(1).and_return(true) ([obj1] | [obj2]).should == [obj1] @@ -54,8 +54,8 @@ describe "Array#|" do obj1 = mock('3') obj2 = mock('4') - obj1.should_receive(:hash).at_least(1).and_return(0) - obj2.should_receive(:hash).at_least(1).and_return(0) + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) obj2.should_receive(:eql?).at_least(1).and_return(false) ([obj1] | [obj2]).should == [obj1, obj2] @@ -74,7 +74,7 @@ describe "Array#|" do it "properly handles an identical item even when its #eql? isn't reflexive" do x = mock('x') - x.should_receive(:hash).at_least(1).and_return(42) + x.stub!(:hash).and_return(42) x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI. ([x] | [x]).should == [x] |