Skip to content

Instantly share code, notes, and snippets.

@ayanko
Last active September 13, 2021 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayanko/5c9a08cf12896814e41cf5ccacf20095 to your computer and use it in GitHub Desktop.
Save ayanko/5c9a08cf12896814e41cf5ccacf20095 to your computer and use it in GitHub Desktop.
Compare and Bench Different UUID generators based on SecureRandom
# frozen_string_literal: true
require 'securerandom'
require 'ulid'
require 'benchmark'
require 'benchmark/ips'
module UuidGenerator
extend self
RANDOM_BYTES = 16
BASE58_ALPHABET = ("0".."9").to_a + ("A".."Z").to_a + ("a".."z").to_a - ["0", "O", "I", "l"]
BASE36_ALPHABET = ("0".."9").to_a + ("a".."z").to_a
BASE32_ALPHABET = ('A'..'Z').to_a + ('2'..'7').to_a
def base64
SecureRandom.urlsafe_base64(RANDOM_BYTES)
end
def base58
SecureRandom.random_bytes(RANDOM_BYTES).unpack("C*").map do |byte|
idx = byte % 64
idx = SecureRandom.random_number(58) if idx >= 58
BASE58_ALPHABET[idx]
end.join
end
def base36
SecureRandom.random_bytes(RANDOM_BYTES).unpack("C*").map do |byte|
idx = byte % 64
idx = SecureRandom.random_number(36) if idx >= 36
BASE36_ALPHABET[idx]
end.join
end
def base32
length = (8 * RANDOM_BYTES / 5.0).ceil
SecureRandom.random_bytes(RANDOM_BYTES).unpack('B*')[0].unpack('a5' * length).map do |byte|
index = byte.to_i(2) << (5 - byte.size)
BASE32_ALPHABET[index]
end.join
end
def base16
SecureRandom.hex(RANDOM_BYTES)
end
def uuid
SecureRandom.uuid
end
def ulid
ULID.generate
end
end
BASE_METHODS = %i[
base64
base58
base36
base32
base16
uuid
ulid
]
puts "\n### Examples\n"
puts "```"
BASE_METHODS.each do |name|
value = UuidGenerator.send(name)
puts "%20s: [%s] %s" % [name, value.length, value]
end
puts "```"
puts "\n### Benchmark 100_000\n"
puts "```"
Benchmark.bm(20) do |x|
BASE_METHODS.each do |name|
x.report("#{name}") do
100_000.times do
UuidGenerator.send(name)
end
end
end
end
puts "```"
puts "\n### Benchmark/IPS\n"
puts "```"
Benchmark.ips do |x|
x.warmup = 0
BASE_METHODS.each do |name|
x.report("#{name}") do
UuidGenerator.send(name)
end
end
x.compare!
end
puts "```"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment