aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-29 07:43:22 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-29 07:43:22 +0000
commita13b6ba18dc4a8b84236bc733f921e33545f6a7f (patch)
treef12916c712e112936e1ac5a25321193ab72b95bd /spec
parentcd6ce13070bb44c99a1583da69d1d62f4693cb47 (diff)
downloadruby-a13b6ba18dc4a8b84236bc733f921e33545f6a7f.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')
-rw-r--r--spec/ruby/core/array/intersection_spec.rb11
-rw-r--r--spec/ruby/core/array/minus_spec.rb10
-rw-r--r--spec/ruby/core/array/union_spec.rb10
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]