Skip to content

Commit be8eed4

Browse files
connorsheaclaude
andcommitted
Make Base.numerify single-pass and allocation-free per digit
Replace the sub-then-gsub double scan with a single gsub whose block tracks whether the leading (non-zero) digit has been emitted, and look digits up in a frozen DIGITS table instead of calling Integer#to_s for every replaced character. Benchmark (Ruby 3.4.9, arm64-darwin25, benchmark-ips): require 'benchmark/ips' require 'faker' Benchmark.ips do |x| x.config(warmup: 1, time: 2) x.report("numerify('###-###-####')") { Faker::Base.numerify('###-###-####') } x.report('PhoneNumber.phone_number') { Faker::PhoneNumber.phone_number } end Results: main: numerify('###-###-####') 486.140k (+/- 4.8%) i/s PhoneNumber.phone_number 100.815k (+/-15.3%) i/s this commit: numerify('###-###-####') 601.743k (+/- 5.2%) i/s (~1.24x) PhoneNumber.phone_number 104.568k (+/-14.7%) i/s (within noise) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 9b07803 commit be8eed4

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

lib/faker.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ class Base
5858
ULetters = Array('A'..'Z')
5959
LLetters = Array('a'..'z')
6060
Letters = ULetters + LLetters
61+
# Frozen digit strings, used to avoid allocating a new string for each
62+
# random digit generated by #numerify.
63+
DIGITS = %w[0 1 2 3 4 5 6 7 8 9].freeze
6164

6265
class << self
6366
attr_reader :flexible_key
@@ -66,9 +69,15 @@ class << self
6669

6770
## by default numerify results do not start with a zero
6871
def numerify(number_string, leading_zero: false)
69-
return number_string.gsub('#') { rand(10).to_s } if leading_zero
70-
71-
number_string.sub('#') { rand(1..9).to_s }.gsub('#') { rand(10).to_s }
72+
leading = !leading_zero
73+
number_string.gsub('#') do
74+
if leading
75+
leading = false
76+
DIGITS[rand(1..9)]
77+
else
78+
DIGITS[rand(10)]
79+
end
80+
end
7281
end
7382

7483
def letterify(letter_string)

0 commit comments

Comments
 (0)