Feature #12639
closedSpeed up require in RubyGems by 5x
Description
This patch makes requiring an already-loaded file approximated 5x faster when the RubyGems mixin for require is present.
Benchmarked via the following script:
require "rubygems"
require "benchmark/ips"
Benchmark.ips do |x|
x.report("ruby") { gem_original_require "rubygems" }
x.report("rubygems") { require "rubygems" }
x.compare!
end
I understand that it's not ideal to add new global functions, and I'd appreciate guidance on where else I could expose this functionality to ruby code.
Thanks :)
Files
Updated by nobu (Nobuyoshi Nakada) almost 10 years ago
I'm not sure if it is acceptable for rubygems to skip loaded features.
+VALUE +rb_f_loaded_feature(VALUE obj, VALUE fname) +{ + return rb_provided(RSTRING_PTR(rb_str_encode_ospath(fname))) ? Qtrue : Qfalse; +}
Why is this function global?
And the argument of RSTRING_PTR should not have side effects.
Updated by hsbt (Hiroshi SHIBATA) almost 8 years ago
- Status changed from Open to Assigned
- Assignee set to hsbt (Hiroshi SHIBATA)
Updated by hsbt (Hiroshi SHIBATA) 15 days ago
- Status changed from Assigned to Closed
The performance gap this patch targeted has been mostly eliminated by incremental optimizations in RubyGems since 2016.
Running the benchmark in the description on current master shows 1.47x (about 80ns per call) instead of 5x, because the require hook now returns early when there are no unresolved dependencies. Additionally, since RubyGems 3.5, Bundler disables the require decoration entirely after bundler/setup via Gem.discover_gems_on_require. The remaining overhead is too small to justify adding a new C API, so I'm closing this issue.