Skip to content

Instantly share code, notes, and snippets.

@oreoshake
Created December 22, 2011 20:34
Show Gist options
  • Save oreoshake/1511751 to your computer and use it in GitHub Desktop.
Save oreoshake/1511751 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'parallel'
require 'benchmark'
# require 'jruby-prof'
############ TEH SETUPZ #############
threads = Parallel.processor_count
n = ARGV[0].to_i
s = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join * n
s_copy = s.dup
chunk_size = (s.size / threads.to_f).ceil
# slice! is the reason for the s.dup call, thought it was elegant until I added the checks
chunks = (1..threads).map { s.slice!(0, chunk_size)}
puts "n = #{n} l = #{s_copy.length} char string, #{threads} threads, #{chunk_size} chunk size"
############ HELPER (stolen from SO, modified) ##############
def collect_values(hashes)
{}.tap{ |r| hashes.each{ |h| h.each{ |k,v| r[k] = r[k].to_i + v } } }
end
# def print_benchmarks
# JRubyProf.print_flat_text(result, n.to_s + "flat.txt")
# JRubyProf.print_graph_html(result, n.to_s + "graph.html")
# JRubyProf.print_tree_html(result, n.to_s + "call_tree.html")
# end
def verify merged_results, string
total_chars = 0
merged_results.each do |char, count|
total_chars += count
raise "fail #{char} #{count} != #{string.count(char)}" unless string.count(char) == count
end
raise "didn't find em all :( #{total_chars} == #{string.length}" unless total_chars == string.length
end
############ TEH CODEZ #############################
merged_results = {}
time = Benchmark.measure do
# result = JRubyProf.profile do
results = Parallel.map(chunks, :in_threads => threads) do |chunk|
counts = {} # temp variable smell? could be an array since we know the bucket's ascii value
chunk.each_char do |c|
counts[c] = counts[c] ? counts[c] + 1 : 1 # faster than counts[c] = counts[c].to_i + 1 ???
end
counts
end
merged_results = collect_values(results)
# end
# print_benchmarks
end
verify(merged_results, s_copy)
puts "original time theaded #{time}"
time = Benchmark.measure do
('a'..'z').each do |char|
merged_results[char] = s_copy.count(char)
end
end
verify(merged_results, s_copy)
puts "time simple count #{time}"
time = Benchmark.measure do
# JRubyProf.profile do
Parallel.map('a'..'z', :in_threads => threads) do |char|
merged_results[char] = s_copy.count(char)
end
# end
# print_benchmarks
end
verify(merged_results, s_copy)
puts "time theaded count #{time}"
puts 'All is good in the hood'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment