2024-05-04 23:12:32 +02:00
|
|
|
require "benchmark"
|
2024-05-10 15:23:28 +02:00
|
|
|
require "./utilities.cr"
|
|
|
|
require "./db-cars.cr"
|
2024-05-04 23:12:32 +02:00
|
|
|
|
2024-05-10 17:57:07 +02:00
|
|
|
# List of environment variables and default values:
|
|
|
|
# ENV["CARNAME"] rescue "Corvet-#{(db_size/2).to_i}"
|
|
|
|
# ENV["CARCOLOR"] rescue "red"
|
|
|
|
# ENV["CARKEYWORD"] rescue "spacious"
|
2024-05-12 14:04:22 +02:00
|
|
|
# ENV["DBSIZE"] rescue 50_000
|
|
|
|
# ENV["DBSIZE_START"] rescue 1_000
|
2024-05-11 01:48:27 +02:00
|
|
|
# ENV["DBSIZE_INCREMENT"] rescue 1_000
|
2024-05-10 17:57:07 +02:00
|
|
|
# ENV["REPORT_DIR"] rescue "results"
|
2024-05-11 01:48:27 +02:00
|
|
|
# ENV["NBRUN"] rescue 100
|
2024-05-12 14:04:22 +02:00
|
|
|
# ENV["MAXINDEXES"] rescue 5_000
|
2024-05-10 17:57:07 +02:00
|
|
|
|
|
|
|
class Context
|
|
|
|
class_property report_dir = "results"
|
2024-05-12 14:04:22 +02:00
|
|
|
class_property max_indexes = 5_000
|
|
|
|
class_property nb_run = 100
|
|
|
|
class_property from = 1_000
|
|
|
|
class_property to = 50_000
|
|
|
|
class_property incr = 1_000
|
2024-05-10 17:57:07 +02:00
|
|
|
end
|
2024-05-04 23:12:32 +02:00
|
|
|
|
2024-05-12 14:34:38 +02:00
|
|
|
# To simplify the creation of graphs, it's better to have fake data for
|
|
|
|
# partitions and tags that won't be actually covered.
|
|
|
|
# 0 means the absence of data.
|
|
|
|
def fake_report(name)
|
|
|
|
durations = Array(Int32).new Context.nb_run, 0
|
|
|
|
File.open("#{Context.report_dir}/#{name}.raw", "w") do |file|
|
|
|
|
durations.each do |d|
|
|
|
|
file.puts d
|
|
|
|
end
|
|
|
|
end
|
|
|
|
puts "#{name}: no report"
|
|
|
|
end
|
2024-05-12 14:04:22 +02:00
|
|
|
def report(storage, name, &block)
|
|
|
|
durations = run_n_times Context.nb_run, &block
|
|
|
|
File.open("#{Context.report_dir}/#{name}.raw", "w") do |file|
|
2024-05-10 17:57:07 +02:00
|
|
|
durations.each do |d|
|
|
|
|
file.puts d
|
|
|
|
end
|
2024-05-04 23:12:32 +02:00
|
|
|
end
|
2024-05-12 14:04:22 +02:00
|
|
|
avr = durations.reduce { |a, b| a + b } / Context.nb_run
|
2024-05-11 01:48:27 +02:00
|
|
|
puts "#{name}: #{avr}"
|
2024-05-10 17:57:07 +02:00
|
|
|
avr
|
2024-05-04 23:12:32 +02:00
|
|
|
end
|
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
def long_operation(text)
|
|
|
|
STDOUT.write "#{text}\r".to_slice
|
|
|
|
yield
|
2024-05-11 01:48:27 +02:00
|
|
|
STDOUT.write " \r".to_slice
|
2024-05-12 14:04:22 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def verbose_add_cars(storage, nbcars, name, max_indexes)
|
|
|
|
long_operation "add #{nbcars} values to #{name}" do
|
|
|
|
add_cars storage, nbcars, max_indexes: max_indexes
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Add first entries, then loop: speed tests, add entries.
|
|
|
|
def prepare_env(storage, name, s_index, s_partition, s_tags, &)
|
|
|
|
verbose_add_cars storage, Context.from, name, max_indexes: Context.max_indexes
|
2024-05-11 01:48:27 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
current = Context.from
|
|
|
|
to = Context.to
|
|
|
|
incr = Context.incr
|
|
|
|
|
|
|
|
while current < to
|
|
|
|
yield storage, current, name, s_index, s_partition, s_tags
|
|
|
|
|
|
|
|
break if current + incr >= to
|
|
|
|
|
|
|
|
verbose_add_cars storage, incr, name, max_indexes: Context.max_indexes
|
|
|
|
current += incr
|
|
|
|
end
|
2024-05-11 01:48:27 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
long_operation "removing #{name} data" { storage.rm_storage_dir }
|
2024-05-11 01:48:27 +02:00
|
|
|
end
|
|
|
|
|
2024-05-24 00:25:28 +02:00
|
|
|
def search_benchmark(storage : DODB::Storage(Car),
|
|
|
|
current_db_size : Int32,
|
|
|
|
name : String,
|
|
|
|
search_name : DODB::Index::Basic(Car),
|
|
|
|
search_color : DODB::Index::Partition(Car),
|
|
|
|
search_keywords : DODB::Index::Tags(Car))
|
|
|
|
name_to_search = ENV["CARNAME"] rescue "Corvet-#{(current_db_size/2).to_i}"
|
|
|
|
color_to_search = ENV["CARCOLOR"] rescue "red"
|
|
|
|
keyword_to_search = ENV["CARKEYWORD"] rescue "spacious"
|
|
|
|
puts "NEW BATCH: db-size #{current_db_size}, name: '#{name_to_search}', color: '#{color_to_search}', tag: '#{keyword_to_search}'"
|
|
|
|
report(storage, "#{name}_#{current_db_size}_index") do
|
|
|
|
corvet = search_name.get name_to_search
|
|
|
|
end
|
|
|
|
if current_db_size <= Context.max_indexes
|
|
|
|
report(storage, "#{name}_#{current_db_size}_partitions") do
|
|
|
|
corvet = search_color.get? color_to_search
|
|
|
|
end
|
|
|
|
report(storage, "#{name}_#{current_db_size}_tags") do
|
|
|
|
corvet = search_keywords.get? keyword_to_search
|
|
|
|
end
|
|
|
|
else
|
|
|
|
fake_report("#{name}_#{current_db_size}_partitions")
|
|
|
|
fake_report("#{name}_#{current_db_size}_tags")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def bench_searches()
|
2024-05-23 14:18:16 +02:00
|
|
|
cars_ram = SPECDB::RAMOnly(Car).new
|
|
|
|
cars_cached = SPECDB::Cached(Car).new
|
2024-05-24 00:25:28 +02:00
|
|
|
cars_fifo = SPECDB::FIFO(Car).new "", 5000 # With only 5_000 entries
|
2024-05-23 14:18:16 +02:00
|
|
|
cars_semi = SPECDB::Uncached(Car).new "-semi"
|
|
|
|
cars_uncached = SPECDB::Uncached(Car).new
|
2024-05-09 18:41:20 +02:00
|
|
|
|
2024-05-11 02:19:03 +02:00
|
|
|
ram_Sby_name, ram_Sby_color, ram_Sby_keywords = ram_indexes cars_ram
|
|
|
|
cached_Sby_name, cached_Sby_color, cached_Sby_keywords = cached_indexes cars_cached
|
2024-05-23 14:18:16 +02:00
|
|
|
fifo_Sby_name, fifo_Sby_color, fifo_Sby_keywords = cached_indexes cars_fifo
|
2024-05-11 02:19:03 +02:00
|
|
|
semi_Sby_name, semi_Sby_color, semi_Sby_keywords = cached_indexes cars_semi
|
|
|
|
uncached_Sby_name, uncached_Sby_color, uncached_Sby_keywords = uncached_indexes cars_uncached
|
2024-05-11 01:48:27 +02:00
|
|
|
|
2024-05-24 00:25:28 +02:00
|
|
|
fn = ->search_benchmark(DODB::Storage(Car), Int32, String, DODB::Index::Basic(Car), DODB::Index::Partition(Car), DODB::Index::Tags(Car))
|
2024-05-11 01:48:27 +02:00
|
|
|
|
2024-05-23 14:18:16 +02:00
|
|
|
prepare_env cars_ram, "ram", ram_Sby_name, ram_Sby_color, ram_Sby_keywords, &fn
|
|
|
|
prepare_env cars_cached, "cached", cached_Sby_name, cached_Sby_color, cached_Sby_keywords, &fn
|
|
|
|
prepare_env cars_fifo, "fifo", fifo_Sby_name, fifo_Sby_color, fifo_Sby_keywords, &fn
|
|
|
|
prepare_env cars_semi, "semi", semi_Sby_name, semi_Sby_color, semi_Sby_keywords, &fn
|
2024-05-12 14:04:22 +02:00
|
|
|
prepare_env cars_uncached, "uncached", uncached_Sby_name, uncached_Sby_color, uncached_Sby_keywords, &fn
|
2024-05-10 17:57:07 +02:00
|
|
|
end
|
2024-05-10 02:57:55 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
def perform_add(storage : DODB::Storage(Car))
|
2024-05-10 02:57:55 +02:00
|
|
|
corvet0 = Car.new "Corvet", "red", [ "shiny", "impressive", "fast", "elegant" ]
|
|
|
|
i = 0
|
2024-05-12 14:04:22 +02:00
|
|
|
perform_benchmark_average Context.nb_run, do
|
2024-05-10 02:57:55 +02:00
|
|
|
corvet = corvet0.clone
|
2024-05-10 15:23:28 +02:00
|
|
|
corvet.name = "Corvet-#{i}"
|
2024-05-10 02:57:55 +02:00
|
|
|
storage << corvet
|
|
|
|
i += 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-05-24 00:25:28 +02:00
|
|
|
def bench_add()
|
2024-05-23 14:18:16 +02:00
|
|
|
cars_ram = SPECDB::RAMOnly(Car).new
|
|
|
|
cars_cached = SPECDB::Cached(Car).new
|
2024-05-24 00:25:28 +02:00
|
|
|
cars_fifo = SPECDB::FIFO(Car).new "", 5_000
|
2024-05-23 14:18:16 +02:00
|
|
|
cars_semi = SPECDB::Uncached(Car).new "-semi"
|
|
|
|
cars_uncached = SPECDB::Uncached(Car).new
|
2024-05-10 17:57:07 +02:00
|
|
|
|
2024-05-11 02:19:03 +02:00
|
|
|
ram_indexes cars_ram
|
|
|
|
cached_indexes cars_cached
|
2024-05-24 00:25:28 +02:00
|
|
|
cached_indexes cars_fifo
|
2024-05-11 02:19:03 +02:00
|
|
|
cached_indexes cars_semi
|
|
|
|
uncached_indexes cars_uncached
|
2024-05-10 02:57:55 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
avr = perform_add(cars_ram)
|
|
|
|
puts "(ram db and indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
2024-05-10 02:57:55 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
avr = perform_add(cars_cached)
|
|
|
|
puts "(cached db and indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
2024-05-10 02:57:55 +02:00
|
|
|
|
2024-05-24 00:25:28 +02:00
|
|
|
avr = perform_add(cars_fifo)
|
|
|
|
puts "(fifo db and cached indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
avr = perform_add(cars_semi)
|
|
|
|
puts "(uncached db but cached indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
2024-05-10 02:57:55 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
avr = perform_add(cars_uncached)
|
|
|
|
puts "(uncached db and indexes) add a value (average on #{Context.nb_run} tries): #{avr}"
|
2024-05-10 17:57:07 +02:00
|
|
|
|
|
|
|
cars_ram.rm_storage_dir
|
|
|
|
cars_cached.rm_storage_dir
|
|
|
|
cars_semi.rm_storage_dir
|
|
|
|
cars_uncached.rm_storage_dir
|
|
|
|
end
|
|
|
|
|
2024-05-24 00:25:28 +02:00
|
|
|
def bench_50_shades_of_fifo()
|
|
|
|
cars_fifo1 = SPECDB::FIFO(Car).new "", 1_000
|
|
|
|
cars_fifo5 = SPECDB::FIFO(Car).new "", 5_000
|
|
|
|
cars_fifo10 = SPECDB::FIFO(Car).new "", 10_000
|
|
|
|
|
|
|
|
fifo_Sby_name1, fifo_Sby_color1, fifo_Sby_keywords1 = cached_indexes cars_fifo1
|
|
|
|
fifo_Sby_name5, fifo_Sby_color5, fifo_Sby_keywords5 = cached_indexes cars_fifo5
|
|
|
|
fifo_Sby_name10, fifo_Sby_color10, fifo_Sby_keywords10 = cached_indexes cars_fifo10
|
|
|
|
|
|
|
|
fn = ->search_benchmark(DODB::Storage(Car), Int32, String, DODB::Index::Basic(Car), DODB::Index::Partition(Car), DODB::Index::Tags(Car))
|
|
|
|
|
|
|
|
prepare_env cars_fifo1, "fifo1", fifo_Sby_name1, fifo_Sby_color1, fifo_Sby_keywords1, &fn
|
|
|
|
prepare_env cars_fifo5, "fifo5", fifo_Sby_name5, fifo_Sby_color5, fifo_Sby_keywords5, &fn
|
|
|
|
prepare_env cars_fifo10, "fifo10", fifo_Sby_name10, fifo_Sby_color10, fifo_Sby_keywords10, &fn
|
|
|
|
end
|
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
ENV["REPORT_DIR"]?.try { |report_dir| Context.report_dir = report_dir }
|
2024-05-10 17:57:07 +02:00
|
|
|
Dir.mkdir_p Context.report_dir
|
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
ENV["MAXINDEXES"]?.try { |it| Context.max_indexes = it.to_i }
|
|
|
|
ENV["NBRUN"]?.try { |it| Context.nb_run = it.to_i }
|
|
|
|
ENV["DBSIZE"]?.try { |it| Context.to = it.to_i }
|
|
|
|
ENV["DBSIZE_START"]?.try { |it| Context.from = it.to_i }
|
|
|
|
ENV["DBSIZE_INCREMENT"]?.try { |it| Context.incr = it.to_i }
|
2024-05-11 01:48:27 +02:00
|
|
|
|
2024-05-12 14:04:22 +02:00
|
|
|
pp! Context.nb_run
|
|
|
|
pp! Context.from
|
|
|
|
pp! Context.to
|
|
|
|
pp! Context.incr
|
|
|
|
pp! Context.max_indexes
|
2024-05-11 01:48:27 +02:00
|
|
|
|
2024-05-24 00:25:28 +02:00
|
|
|
if ARGV.size == 0
|
|
|
|
puts "Usage: benchmark-cars (fifo|search|add)"
|
|
|
|
exit 0
|
|
|
|
end
|
|
|
|
|
|
|
|
case ARGV[0]
|
|
|
|
when /fifo/
|
|
|
|
bench_50_shades_of_fifo
|
|
|
|
when /search/
|
|
|
|
bench_searches
|
|
|
|
when /add/
|
|
|
|
bench_add
|
|
|
|
else
|
|
|
|
puts "Usage: benchmark-cars (fifo|search|add)"
|
|
|
|
end
|