Skip to content

Commit bbd3f24

Browse files
Document lazy load experiment results (#3205)
* Document lazy load experiment results Closes #3199 Co-Authored-By: Thiago Araujo <thd.araujo@gmail.com> * Updated results after latest commits Changes can be found in this branch: #3211 --------- Co-authored-by: Thiago Araujo <thd.araujo@gmail.com>
1 parent 1ca97a0 commit bbd3f24

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

experiments/lazy_load.md

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

0 commit comments

Comments
 (0)