Skip to content

Instantly share code, notes, and snippets.

@gregspurrier
Created November 7, 2010 21:03
Show Gist options
  • Save gregspurrier/666787 to your computer and use it in GitHub Desktop.
Save gregspurrier/666787 to your computer and use it in GitHub Desktop.
Exploring performance characteristics of implementations of Enumerable#reorder_by
# Example code and benchmark harness for http://blog.gregspurrier.com/articles/arbitrary-reordering-of-ruby-arrays
require 'rubygems'
require 'rspec'
module Enumerable
def reorder_by1(order, &key_proc)
order.map do |x|
find {|obj| key_proc.call(obj) == x}
end
end
end
module Enumerable
def reorder_by2(order, &key_proc)
indexed = map {|x| [key_proc.call(x), x]}
order.map do |x|
indexed.find {|pair| pair.first == x}.last
end
end
end
module Enumerable
def reorder_by(order, &key_proc)
index_to_obj = inject({}) do |hash, obj|
hash[key_proc.call(obj)] = obj
hash
end
order.map do |x|
index_to_obj[x]
end
end
end
describe "reordering" do
before(:each) do
@objects = [:a, :b, :c, :d, :e]
@ordering = %w(e b c d a)
@expected = [:e, :b, :c, :d, :a]
end
context 'naive implementation' do
it 'reorders the objects in the desired order' do
@objects.reorder_by1(@ordering, &:to_s).should == @expected
end
end
context 'memoized result of the key proc' do
it 'reorders the objects in the desired order' do
@objects.reorder_by2(@ordering, &:to_s).should == @expected
end
end
context 'hash-based lookup of memoized key proc' do
it 'reorders the objects in the desired order' do
@objects.reorder_by(@ordering, &:to_s).should == @expected
end
end
end
# Benchmarks
if ENV['BM'] == 'true'
require 'benchmark'
original = ('aa'..'bz').map {|x| x.to_sym}
desired = ('aa'..'bz').to_a.shuffle
Benchmark.bm do |b|
b.report('reorder_by1:') do
10_000.times do
original.reorder_by1(desired, &:to_s)
end
end
b.report('reorder_by2:') do
10_000.times do
original.reorder_by2(desired, &:to_s)
end
end
b.report('reorder_by:') do
10_000.times do
original.reorder_by(desired, &:to_s)
end
end
end
end
@jonelf
Copy link

jonelf commented Feb 3, 2014

How about storing the sort order in a hash and then simply use Enumerable#sort_by?
Something like this https://gist.github.com/jonelf/8792448

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment