Skip to content

Commit

Permalink
Merge pull request #1068 from laserlemon/random-order-performance
Browse files Browse the repository at this point in the history
Use Array#shuffle for random spec ordering
  • Loading branch information
myronmarston committed Sep 5, 2013
2 parents 120fb71 + 7018b85 commit 665f5a4
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
42 changes: 42 additions & 0 deletions benchmarks/sort_by_v_shuffle.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require "benchmark"

# This benchmark demonstrates the speed of Array#shuffle versus sorting by
# random numbers. This is in reference to ordering examples using the
# --order=rand command line flag. Array#shuffle also respects seeded random via
# Kernel.srand.

LIST = (1..1_000).to_a.freeze

Benchmark.bmbm do |x|
x.report("sort_by") do
1_000.times do
LIST.sort_by { Kernel.rand(LIST.size) }
end
end

x.report("shuffle") do
1_000.times do
LIST.shuffle
end
end
end

# Ruby 2.0
#
# 21x over 100 list elements:
#
# user system total real
# sort_by 0.080000 0.000000 0.080000 ( 0.074924)
# shuffle 0.000000 0.000000 0.000000 ( 0.003535)
#
# 27x over 1,000 list elements:
#
# user system total real
# sort_by 0.870000 0.000000 0.870000 ( 0.874661)
# shuffle 0.030000 0.000000 0.030000 ( 0.031949)
#
# 31x over 10,000 list elements:
#
# user system total real
# sort_by 10.690000 0.010000 10.700000 ( 10.695433)
# shuffle 0.330000 0.010000 0.340000 ( 0.342375)
2 changes: 1 addition & 1 deletion lib/rspec/core/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ def randomize?
# @private
RANDOM_ORDERING = lambda do |list|
Kernel.srand RSpec.configuration.seed
ordering = list.sort_by { Kernel.rand(list.size) }
ordering = list.shuffle
Kernel.srand # reset random generation
ordering
end
Expand Down
27 changes: 24 additions & 3 deletions spec/rspec/core/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1333,10 +1333,12 @@ def metadata_hash(*args)
end

it 'can set random ordering' do
config.force :seed => "rand:37"
config.force :order => "rand:37"
RSpec.stub(:configuration => config)
list = [1, 2, 3, 4].extend(Extensions::Ordered::Examples)
Kernel.should_receive(:rand).and_return(3, 1, 4, 2)
Kernel.should_receive(:srand).ordered.once.with(37)
list.should_receive(:shuffle).ordered.and_return([2, 4, 1, 3])
Kernel.should_receive(:srand).ordered.once.with(no_args)
expect(list.ordered).to eq([2, 4, 1, 3])
end

Expand Down Expand Up @@ -1377,6 +1379,23 @@ def metadata_hash(*args)
end

describe '#order=' do
context 'given "random"' do
before { config.order = 'random:123' }

it 'sets order to "random"' do
expect(config.order).to eq('random')
end

it 'sets up random ordering' do
RSpec.stub(:configuration => config)
list = [1, 2, 3, 4].extend(Extensions::Ordered::Examples)
Kernel.should_receive(:srand).ordered.with(123)
list.should_receive(:shuffle).ordered.and_return([2, 4, 1, 3])
Kernel.should_receive(:srand).ordered.with(no_args)
expect(list.ordered).to eq([2, 4, 1, 3])
end
end

context 'given "random:123"' do
before { config.order = 'random:123' }

Expand All @@ -1391,7 +1410,9 @@ def metadata_hash(*args)
it 'sets up random ordering' do
RSpec.stub(:configuration => config)
list = [1, 2, 3, 4].extend(Extensions::Ordered::Examples)
Kernel.should_receive(:rand).and_return(3, 1, 4, 2)
Kernel.should_receive(:srand).ordered.with(123)
list.should_receive(:shuffle).ordered.and_return([2, 4, 1, 3])
Kernel.should_receive(:srand).ordered.with(no_args)
expect(list.ordered).to eq([2, 4, 1, 3])
end
end
Expand Down

0 comments on commit 665f5a4

Please sign in to comment.