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)
Motivation / Background
This Pull Request has been created because I want Faker to be faster and use less memory in DB seeds and automated tests.
This PR was generated using Claude Code with Fable 5. The change has been reviewed by me and tested by me.
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.
Additional information
Benchmark (Ruby 3.4.9, arm64-darwin25, benchmark-ips):
And a memory benchmark of the change to show the difference in memory usage.
Results (per call, averaged over 1000 calls)
Checklist
Before submitting the PR make sure the following are checked:
If you're proposing a new generator or locale: