1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
# Lazy load experiment results
- Branch: sb-ta/lazy-load-experiment
- Date: February 10th, 2026
- Owner(s): Stefanni Brasil and Thiago Araujo
## Impact
Using `const_missing` to lazy load generators was an idea from talking with Jeremy Evans, who kindly responded our questions about improving faker's performance.
### Changes needed
Would require loading `faker/music` and `faker/internet` first, before the nested namespaces such as `Faker::Music::BossaNova`,
as they inherit from class `Music`.
#### File location changes
To prevent other generators from erroring out due to namespace clashing, some generators have to be moved around (ex. `Faker::Quote` was moved from `/faker/quotes/quote` to `faker/default/quote`). Users can still use the generators as before, their namespaces didn't change.
### Benefits
- no additional dependencies needed
- code is extremely faster
- we can enable this as an opt-in configuration
- allows for users to create external generators in a transparent way
## Results
Machine specs: Apple M1 Pro 16GB memory on MacOS Sequoia 15.7.3..
profiler:
- [LAZY_LOAD=1 bundle exec vernier run -- ruby -e "require 'faker'"](https://share.firefox.dev/46biNAs)
- [bundle exec vernier run -- ruby -e "require 'faker'"](https://share.firefox.dev/4ams9vM)
benchmark:
```sh
benchmark % ruby load.rb
ruby 3.3.10 (2025-10-23 revision 343ea05002) [arm64-darwin24]
Warming up --------------------------------------
require 1.000 i/100ms
lazyload 1.000 i/100ms
Calculating -------------------------------------
require 4.698 (± 0.0%) i/s (212.88 ms/i) - 24.000 in 5.133782s
lazyload 9.751 (± 0.0%) i/s (102.55 ms/i) - 49.000 in 5.032161s
Comparison:
require: 4.7 i/s
lazyload: 9.8 i/s - 2.08x faster
```
## Artifacts
### Scripts
Constants were registered using this script:
```ruby
# lazy_load.rb
CATEGORIES = {
Blockchain: 'blockchain',
Books: 'books',
Creature: 'creature',
Default: 'default',
Fantasy: 'fantasy',
Games: 'games',
JapaneseMedia: 'japanese_media',
Locations: 'locations',
Movies: 'movies',
Music: 'music',
Quotes: 'quotes',
Religion: 'religion',
Sports: 'sports',
Travel: 'travel',
TvShows: 'tv_shows'
}.freeze
def template(key)
"# frozen_string_literal: true
module Faker
class #{key}
if ENV['LAZY_LOAD'] == '1'
Faker.lazy_load(self)
end
end
end"
end
CATEGORIES.each do |key, value|
File.write(File.join('lib', 'faker', "#{value}.rb"), template(key))
end
```
|