Skip to content

Instantly share code, notes, and snippets.

@wbailey
Created March 4, 2011 07:31
Show Gist options
  • Save wbailey/854308 to your computer and use it in GitHub Desktop.
Save wbailey/854308 to your computer and use it in GitHub Desktop.
Fun with ruby arrays and hashes
# usage: array_merge.rb --data_file=filename --limits=10,20,30
require 'rubygems'
require 'vr_script'
require 'benchmark'
include Benchmark
class Array
def to_hash_using_inject_push( use_array )
Hash[*(0 .. self.size).inject( [] ) { |r,i| r.push( self[i], use_array[i] ) }]
end
def to_hash_using_zip_flatten( use_array )
Hash[*self.zip( use_array ).flatten]
end
def to_hash_using_each_with_index( use_array )
h = Hash.new
self.each_with_index { |k,i| h[k] = use_array[i] }
h
end
def to_hash_using_brute_force( use_array )
h = Hash.new
( 0 ... self.size ).each { |i| h[self[i]] = use_array[i] }
h
end
end
class BenchmarkArrayToHash < VR::Script::Base
def build_test_arrays( use_size )
@a1 = [*0..use_size]
@a2 = [*0..use_size]
end
def initialize
clo = { :data_file => { :default => 'benchmark.data' }, :limits => { :default => "10, 50, 100" }, }
super( clo ) do
data_file = get_option( :data_file )
limits = get_option( :limits )
file = File.new( data_file, 'w' )
file.puts '(CPU)'.rjust( 40 ) + '(Real)'.rjust(55)
file.puts 'size ' + ('bf'.rjust( 13 ) + 'ewi'.rjust( 13) + 'ip'.rjust( 13 ) + 'zf'.rjust( 13 )) * 2
limits.split( ',' ).each do |val|
build_test_arrays( val.to_i )
results = Array.new
results[0] = Benchmark.measure { @a1.to_hash_using_brute_force( @a2 ) }
results[1] = Benchmark.measure { @a1.to_hash_using_each_with_index( @a2 ) }
results[2] = Benchmark.measure { @a1.to_hash_using_inject_push( @a2 ) }
results[3] = Benchmark.measure { @a1.to_hash_using_zip_flatten( @a2 ) }
# Produce a line that we can use to plot in gnuplot
file.puts results.inject( "#{val.to_s.ljust( 10 )} " ) { |line,res| line << "#{res.format( '%12.8u' )} " << "#{res.format( '%12.8u' )}" }
Benchmark.bm do |b|
b.report( 'brute force' ) { @a1.to_hash_using_brute_force( @a2 ) }
b.report( 'each with index' ) { @a1.to_hash_using_each_with_index( @a2 ) }
b.report( 'inject/push' ) { @a1.to_hash_using_inject_push( @a2 ) }
b.report( 'zip/flatten' ) { @a1.to_hash_using_zip_flatten( @a2 ) }
end
end
end
end
end
BenchmarkArrayToHash.new.run
irb(main):007:0> a1 = [ :a, :b, :c ]
=> [:a, :b, :c]
irb(main):008:0> a2 = [ 1, 2, 3, ]
=> [1, 2, 3]
...
=> {:b=>2, :a=>1, :c=>3}
rb(main):003:0> h = Hash.new
=> {}
irb(main):005:0> ( 0 .. 2 ).each { |i| h[a1[i]] = a2[i] }
=> [:a, :b, :c]
irb(main):006:0> h
=> {:b=>2, :a=>1, :c=>3}
irb(main):003:0> h = Hash.new
=> {}
irb(main):005:0> a1.each_with_index { |key,idx| h[key] = a2[idx] }
=> [:a, :b, :c]
irb(main):006:0> h
=> {:b=>2, :a=>1, :c=>3}
irb(main):012:0> Hash[ :a, 1, :b, 2, :c, 3 ]
=> {:b=>2, :a=>1, :c=>3}
irb(main):014:0> a1.zip( a2 ).flatten
=> [:a, 1, :b, 2, :c, 3]
irb(main):018:0> Hash[*a1.zip(a2).flatten]
=> {:b=>2, :a=>1, :c=>3}
irb(main):019:0> Hash[*(0..2).inject( [] ) { |r,i| r.push( a1[i], a2[i] ) }]
=> {:b=>2, :a=>1, :c=>3}
irb(main):013:0> a1.zip( a2 )
=> [[:a, 1], [:b, 2], [:c, 3]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment