Skip to content

Instantly share code, notes, and snippets.

@generalmimon
Last active July 29, 2024 17:14
Show Gist options
  • Save generalmimon/331361de0ee72d4ab1f952ea92c8bec7 to your computer and use it in GitHub Desktop.
Save generalmimon/331361de0ee72d4ab1f952ea92c8bec7 to your computer and use it in GitHub Desktop.
bytes_terminate() benchmark for the Kaitai Struct Ruby runtime library: https://github.com/kaitai-io/kaitai_struct_ruby_runtime/blob/cc99af6b/lib/kaitai/struct/struct.rb#L437
#!/usr/bin/env ruby
=begin
Usage:
$ ruby bench-bytes_terminate.rb
You need to install https://rubygems.org/gems/benchmark-ips first:
$ gem install benchmark-ips
=end
require 'benchmark/ips'
require 'json'
TERM_HALFWAY = 1
TERM_END = 2
TERM_MISSING = 3
JSON_TERM_POS_TABLE = {
'halfway' => TERM_HALFWAY,
'end' => TERM_END,
'missing' => TERM_MISSING,
}
conf = JSON.load_file('bench_config.json', {symbolize_names: true})
TERM_POS = JSON_TERM_POS_TABLE.fetch(conf[:term_pos])
raise unless [true, false].include?(conf[:include_term])
INCLUDE_TERM = conf[:include_term]
raise unless conf[:workload_size].is_a?(Integer)
WORKLOAD_SIZE = conf[:workload_size]
def bytes_terminate_old(bytes, term, include_term)
new_len = 0
max_len = bytes.length
while bytes.getbyte(new_len) != term and new_len < max_len
new_len += 1
end
new_len += 1 if include_term and new_len < max_len
bytes[0, new_len]
end
def bytes_terminate_index(bytes, term, include_term)
term_index = bytes.index(term.chr)
if term_index.nil?
bytes.dup
else
bytes[0, term_index + (include_term ? 1 : 0)]
end
end
def bytes_terminate_index_plus(bytes, term, include_term)
term_index = bytes.index(term.chr)
if term_index.nil?
+bytes
else
bytes[0, term_index + (include_term ? 1 : 0)]
end
end
prng = Random.new
term = prng.rand(256)
repl = 0x00
if repl == term
repl = 0xff
end
repl = repl.chr(Encoding::ASCII_8BIT)
buf = prng.bytes(WORKLOAD_SIZE)
buf.each_byte.with_index do |b, i|
buf[i] = repl if b == term
end
if TERM_POS == TERM_HALFWAY
buf.setbyte(buf.length / 2, term)
elsif TERM_POS == TERM_END
buf.setbyte(-2, term)
end
exp =
if TERM_POS == TERM_HALFWAY
buf.length / 2 + (INCLUDE_TERM ? 1 : 0)
elsif TERM_POS == TERM_END
buf.length - 2 + (INCLUDE_TERM ? 1 : 0)
elsif TERM_POS == TERM_MISSING
buf.length
end
act = bytes_terminate_old(buf, term, INCLUDE_TERM).length
raise "expected #{exp} but got #{act}" unless act == exp
act = bytes_terminate_index(buf, term, INCLUDE_TERM).length
raise "expected #{exp} but got #{act}" unless act == exp
act = bytes_terminate_index_plus(buf, term, INCLUDE_TERM).length
raise "expected #{exp} but got #{act}" unless act == exp
Benchmark.ips do |x|
# x.report("index_plus") do
# bytes_terminate_index_plus(buf, term, INCLUDE_TERM)
# end
x.report("index") do
bytes_terminate_index(buf, term, INCLUDE_TERM)
end
x.report("old") do
bytes_terminate_old(buf, term, INCLUDE_TERM)
end
x.compare!
end
$ echo '{"term_pos": "end", "include_term": false, "workload_size": 1024}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 243.080k i/100ms
old 2.299k i/100ms
Calculating -------------------------------------
index 2.539M (± 1.1%) i/s - 12.883M in 5.074435s
old 23.795k (± 1.0%) i/s - 119.548k in 5.024546s
Comparison:
index: 2539171.4 i/s
old: 23795.3 i/s - 106.71x slower
$ echo '{"term_pos": "halfway", "include_term": false, "workload_size": 2048}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 257.467k i/100ms
old 2.335k i/100ms
Calculating -------------------------------------
index 2.561M (± 0.9%) i/s - 12.873M in 5.026704s
old 23.788k (± 2.6%) i/s - 119.085k in 5.010115s
Comparison:
index: 2561190.3 i/s
old: 23787.6 i/s - 107.67x slower
$ echo '{"term_pos": "missing", "include_term": false, "workload_size": 1024}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 418.152k i/100ms
old 2.375k i/100ms
Calculating -------------------------------------
index 4.145M (± 1.1%) i/s - 20.908M in 5.044290s
old 23.934k (± 0.5%) i/s - 121.125k in 5.060964s
Comparison:
index: 4145345.9 i/s
old: 23933.7 i/s - 173.20x slower
$ echo '{"term_pos": "end", "include_term": false, "workload_size": 4096}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 119.994k i/100ms
old 576.000 i/100ms
Calculating -------------------------------------
index 1.872M (± 3.6%) i/s - 9.360M in 5.008434s
old 5.980k (± 0.7%) i/s - 29.952k in 5.008889s
Comparison:
index: 1871917.7 i/s
old: 5980.1 i/s - 313.03x slower
$ echo '{"term_pos": "halfway", "include_term": false, "workload_size": 8192}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 193.497k i/100ms
old 585.000 i/100ms
Calculating -------------------------------------
index 1.930M (± 2.4%) i/s - 9.675M in 5.016233s
old 5.863k (± 3.5%) i/s - 29.835k in 5.096169s
Comparison:
index: 1929994.1 i/s
old: 5862.8 i/s - 329.19x slower
$ echo '{"term_pos": "missing", "include_term": false, "workload_size": 4096}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 360.731k i/100ms
old 603.000 i/100ms
Calculating -------------------------------------
index 3.565M (± 1.0%) i/s - 18.037M in 5.060550s
old 6.012k (± 0.7%) i/s - 30.150k in 5.015320s
Comparison:
index: 3564520.8 i/s
old: 6011.9 i/s - 592.91x slower
$ echo '{"term_pos": "end", "include_term": false, "workload_size": 16384}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 42.668k i/100ms
old 149.000 i/100ms
Calculating -------------------------------------
index 303.517k (± 2.6%) i/s - 1.536M in 5.064298s
old 1.486k (± 1.2%) i/s - 7.450k in 5.013941s
Comparison:
index: 303517.2 i/s
old: 1486.1 i/s - 204.24x slower
$ echo '{"term_pos": "halfway", "include_term": false, "workload_size": 32768}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 32.236k i/100ms
old 148.000 i/100ms
Calculating -------------------------------------
index 325.857k (± 3.0%) i/s - 1.644M in 5.049964s
old 1.491k (± 1.0%) i/s - 7.548k in 5.061962s
Comparison:
index: 325856.6 i/s
old: 1491.3 i/s - 218.51x slower
$ echo '{"term_pos": "missing", "include_term": false, "workload_size": 16384}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index 279.347k i/100ms
old 136.000 i/100ms
Calculating -------------------------------------
index 2.833M (± 0.8%) i/s - 14.247M in 5.029648s
old 1.504k (± 0.8%) i/s - 7.616k in 5.062980s
Comparison:
index: 2832731.1 i/s
old: 1504.3 i/s - 1883.03x slower
$ echo '{"term_pos": "missing", "include_term": false, "workload_size": 1024}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index_plus 422.285k i/100ms
index 331.757k i/100ms
Calculating -------------------------------------
index_plus 4.334M (± 0.9%) i/s - 21.959M in 5.067086s
index 3.806M (± 0.9%) i/s - 19.242M in 5.055957s
Comparison:
index_plus: 4334014.0 i/s
index: 3806103.2 i/s - 1.14x slower
$ echo '{"term_pos": "missing", "include_term": false, "workload_size": 4096}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index_plus 407.681k i/100ms
index 362.686k i/100ms
Calculating -------------------------------------
index_plus 4.099M (± 0.5%) i/s - 20.792M in 5.071932s
index 3.609M (± 0.6%) i/s - 18.134M in 5.025432s
Comparison:
index_plus: 4099483.6 i/s
index: 3608631.0 i/s - 1.14x slower
$ echo '{"term_pos": "missing", "include_term": false, "workload_size": 16384}' > bench_config.json && ruby bench-bytes_terminate.rb
ruby 3.3.4 (2024-07-09 revision be1089c8ec) [x86_64-linux]
Warming up --------------------------------------
index_plus 321.927k i/100ms
index 285.162k i/100ms
Calculating -------------------------------------
index_plus 3.211M (± 0.9%) i/s - 16.096M in 5.013197s
index 2.838M (± 1.7%) i/s - 14.258M in 5.025916s
Comparison:
index_plus: 3211037.2 i/s
index: 2837859.8 i/s - 1.13x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment