Skip to content

Commit

Permalink
Move benchmark and call_tree tasks closer to one another
Browse files Browse the repository at this point in the history
  • Loading branch information
gonzedge committed Jan 6, 2017
1 parent 6def0fd commit 37d46d2
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 102 deletions.
17 changes: 17 additions & 0 deletions lib/rambling/trie/tasks/helpers/performance_report.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class PerformanceReport
attr_reader :output

def initialize output = $stdout.dup
@output = output
end

def start name
output.puts
output.puts "#{name} for rambling-trie version #{Rambling::Trie::VERSION}"
output.puts
end

def finish
output.close
end
end
1 change: 1 addition & 0 deletions lib/rambling/trie/tasks/performance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'flamegraph'
require_relative 'helpers/path'
require_relative 'helpers/time'
require_relative 'helpers/performance_report'
require_relative 'performance/directory'
require_relative 'performance/benchmark'
require_relative 'performance/flamegraph'
Expand Down
66 changes: 21 additions & 45 deletions lib/rambling/trie/tasks/performance/benchmark.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
require_relative '../helpers/path'

namespace :performance do
include Helpers::Path

class BenchmarkReport
attr_reader :output

def initialize output
@output = output
end

def finish
output.close
end
end

class BenchmarkMeasurement
def initialize output
@output = output
Expand Down Expand Up @@ -42,10 +28,6 @@ def perform times, params = nil
end
end

def banner
output.puts "\nBenchmark for rambling-trie version #{Rambling::Trie::VERSION}"
end

private

attr_reader :output
Expand All @@ -64,23 +46,20 @@ def measure times, param = nil
end
end

def benchmark_report= benchmark_report
@benchmark_report = benchmark_report
def performance_report= performance_report
@performance_report = performance_report
end

def benchmark_report
Rake::Task['performance:benchmark:output:stdout'].invoke unless @benchmark_report

@benchmark_report
def performance_report
@performance_report ||= PerformanceReport.new
end

def output
benchmark_report.output
performance_report.output
end

def generate_lookups_benchmark filename = nil
measure = BenchmarkMeasurement.new output
measure.banner

trie = Rambling::Trie.create dictionary
compressed_trie = Rambling::Trie.create(dictionary).compress!
Expand All @@ -102,7 +81,6 @@ def generate_lookups_benchmark filename = nil

def generate_scans_benchmark filename = nil
measure = BenchmarkMeasurement.new output
measure.banner

words = {
hi: 1_000,
Expand All @@ -128,38 +106,37 @@ def generate_scans_benchmark filename = nil

namespace :benchmark do
namespace :output do
desc 'Set task reporting output to stdout'
task :stdout do
self.benchmark_report = BenchmarkReport.new IO.new(1)
end

desc 'Set task reporting output to file'
task file: ['performance:directory'] do
path = path 'reports', Rambling::Trie::VERSION, 'benchmark'
file = File.open path, 'a+'
self.benchmark_report = BenchmarkReport.new file
self.performance_report = PerformanceReport.new file
end

desc 'Close output stream'
task :close do
benchmark_report.finish unless benchmark_report.nil?
performance_report.finish
end
end

desc 'Output banner'
task :banner do
performance_report.start 'Benchmark'
end

desc 'Generate lookups performance benchmark report'
task :lookups do
task lookups: :banner do
generate_lookups_benchmark
end

desc 'Generate scans performance benchmark report'
task :scans do
task scans: :banner do
generate_scans_benchmark
end

desc 'Generate creation performance benchmark report'
task :creation do
task creation: :banner do
measure = BenchmarkMeasurement.new output
measure.banner

output.puts '==> Creation'
output.puts '`Rambling::Trie.create`'
Expand All @@ -170,9 +147,8 @@ def generate_scans_benchmark filename = nil
end

desc 'Generate compression performance benchmark report'
task :compression do
task compression: :banner do
measure = BenchmarkMeasurement.new output
measure.banner

output.puts '==> Compression'
output.puts '`compress!`'
Expand All @@ -188,17 +164,17 @@ def generate_scans_benchmark filename = nil

desc 'Generate all performance benchmark reports'
task all: [
'creation',
'compression',
'lookups',
'scans',
:creation,
:compression,
:lookups,
:scans,
]

namespace :all do
desc "Generate and store performance benchmark report in reports/#{Rambling::Trie::VERSION}"
task save: [
'output:file',
'all'
:all
]
end

Expand Down
123 changes: 66 additions & 57 deletions lib/rambling/trie/tasks/performance/profile/call_tree.rb
Original file line number Diff line number Diff line change
@@ -1,62 +1,71 @@
require_relative '../../helpers/path'
require_relative '../../helpers/time'

namespace :performance do
namespace :profile do
include Helpers::Path
include Helpers::Time

def profile times, params, path
params = Array params
params << nil unless params.any?
def performance_report
@performance_report ||= PerformanceReport.new
end

def output
performance_report.output
end

class CallTreeProfile
def initialize dirname
@dirname = dirname
end

def perform times, params = nil
params = Array params
params << nil unless params.any?

result = RubyProf.profile merge_fibers: true do
params.each do |param|
times.times do
yield param
result = RubyProf.profile merge_fibers: true do
params.each do |param|
times.times do
yield param
end
end
end

path = path 'reports', Rambling::Trie::VERSION, 'call-tree', time, dirname
FileUtils.mkdir_p path
printer = RubyProf::CallTreePrinter.new result
printer.print path: path
end

printer = RubyProf::CallTreePrinter.new result
printer.print path: path
private

attr_reader :dirname
end

def generate_lookups_call_tree
puts 'Generating call tree profiling reports for lookups...'

puts "\nCall Tree profile for rambling-trie version #{Rambling::Trie::VERSION}"
output.puts 'Generating call tree profiling reports for lookups...'

words = %w(hi help beautiful impressionism anthropological)

trie = Rambling::Trie.create dictionary
compressed_trie = Rambling::Trie.create(dictionary).compress!

[ trie, compressed_trie ].each do |trie|
filename = "profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}-word"
path = path 'reports', Rambling::Trie::VERSION, 'call-tree', time, filename
FileUtils.mkdir_p path
prefix = "profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}"

profile 200_000, words, path do
call_tree_profile = CallTreeProfile.new "#{prefix}-word"
call_tree_profile.perform 200_000, words do
trie.word? word
end

filename = "profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}-partial-word"
path = path 'reports', Rambling::Trie::VERSION, 'call-tree', time, filename
FileUtils.mkdir_p path

profile 200_000, words, path do
call_tree_profile = CallTreeProfile.new "#{prefix}-partial-word"
call_tree_profile.perform 200_000, words do
trie.partial_word? word
end
end

puts 'Done'
output.puts 'Done'
end

def generate_scans_call_tree
puts 'Generating call tree profiling reports for scans...'

puts "\nCall Tree profile for rambling-trie version #{Rambling::Trie::VERSION}"
output.puts 'Generating call tree profiling reports for scans...'

words = {
hi: 1_000,
Expand All @@ -70,68 +79,68 @@ def generate_scans_call_tree
compressed_trie = Rambling::Trie.create(dictionary).compress!

[ trie, compressed_trie ].each do |trie|
filename = "profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}-scan"
path = path 'reports', Rambling::Trie::VERSION, 'call-tree', time, filename
FileUtils.mkdir_p path
dirname = "profile-#{trie.compressed? ? 'compressed' : 'uncompressed'}-scan"
call_tree_profile = CallTreeProfile.new dirname

words.each do |word, times|
profile times, word.to_s, path do |word|
trie.scan(word).size
call_tree_profile.perform times, word.to_s do |word|
trie.partial_word? word
end
end
end

puts 'Done'
output.puts 'Done'
end

namespace :call_tree do
desc 'Output banner'
task :banner do
performance_report.start 'Call Tree profile'
end

desc 'Generate call tree profiling reports for creation'
task creation: ['performance:directory'] do
puts 'Generating call tree profiling reports for creation...'
puts "\nCall Tree profile for rambling-trie version #{Rambling::Trie::VERSION}"
filename = "profile-new-trie"
path = path 'reports', Rambling::Trie::VERSION, 'call-tree', time, filename
FileUtils.mkdir_p path
task creation: ['performance:directory', :banner] do
output.puts 'Generating call tree profiling reports for creation...'

profile 5, nil, path do
call_tree_profile = CallTreeProfile.new 'profile-new-trie'
call_tree_profile.perform 5 do
trie = Rambling::Trie.create dictionary
end

output.puts 'Done'
end

desc 'Generate call tree profiling reports for compression'
task compression: ['performance:directory'] do
puts 'Generating call tree profiling reports for compression...'
puts "\nCall Tree profile for rambling-trie version #{Rambling::Trie::VERSION}"

filename = "profile-compressed-trie"
path = path 'reports', Rambling::Trie::VERSION, 'call-tree', time, filename
FileUtils.mkdir_p path
task compression: ['performance:directory', :banner] do
output.puts 'Generating call tree profiling reports for compression...'

tries = []
5.times { tries << Rambling::Trie.create(dictionary) }

profile 5, tries, path do |trie|
trie.compress!
nil
call_tree_profile = CallTreeProfile.new 'profile-compressed-trie'
call_tree_profile.perform 5, tries do |trie|
trie.compress!; nil
end

output.puts 'Done'
end

desc 'Generate call tree profiling reports for lookups'
task lookups: ['performance:directory'] do
task lookups: ['performance:directory', :banner] do
generate_lookups_call_tree
end

desc 'Generate call tree profiling reports for scans'
task scans: ['performance:directory'] do
task scans: ['performance:directory', :banner] do
generate_scans_call_tree
end

desc 'Generate all call tree profiling reports'
task all: [
'creation',
'compression',
'lookups',
'scans',
:creation,
:compression,
:lookups,
:scans,
]
end
end
Expand Down

0 comments on commit 37d46d2

Please sign in to comment.