Last active
July 29, 2024 17:14
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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