Implement loaded feature caching to reduce load path searching. #452

Merged
merged 4 commits into from Dec 18, 2012

Projects

None yet

3 participants

@headius
Member
headius commented Dec 17, 2012

This is an idea borrowed from Ruby 2.0.0, whereby the short names
of loaded features are held in an internal structure and used as
a first-line cache to avoid re-searching for re-required files.
Before this patch, in both JRuby and MRI, re-required files had to
do a full load path search every time because the loaded features
list only held the full canonical paths, which are only available
after searching for the proper load path entry under which the
file exists. With the patch in place, re-required files will
usually be immediately found in the cache.

The population and invalidation of the cache proceeds as follows:

  • A reference is held to a dup of the loaded features array. When
    this reference is captured.
  • When adding a new feature to loaded features, we re-capture
    the dup'ed features array and add the short name to a separate
    internal cache.
  • As long as the dup'ed features array is non-null and matches
    the current loaded features array, we know we can safely use the
    loaded features index.
  • When the dup'ed features array does not match, we clear the
    loaded features index and start populating it anew. Since most
    typical Ruby code does not modify the loaded features array
    directly, this should be rare.

Numbers with and without this change show the performance gained.
The following benchmark populates load path with 1000 entries and
requires the same file 1000 times.

Before:

system ~/projects/jruby $ rvm jruby do jruby bench_loaded_features.rb 1000 1000
8.110000 3.880000 11.990000 ( 9.708000)

After:

system ~/projects/jruby $ jruby bench_loaded_features.rb 1000 1000
0.990000 0.050000 1.040000 ( 0.324000)

headius and others added some commits Dec 17, 2012
@headius headius Implement loaded feature caching to reduce load path searching.
This is an idea borrowed from Ruby 2.0.0, whereby the short names
of loaded features are held in an internal structure and used as
a first-line cache to avoid re-searching for re-required files.
Before this patch, in both JRuby and MRI, re-required files had to
do a full load path search every time because the loaded features
list only held the full canonical paths, which are only available
after searching for the proper load path entry under which the
file exists. With the patch in place, re-required files will
usually be immediately found in the cache.

The population and invalidation of the cache proceeds as follows:

* A reference is held to a dup of the loaded features array. When
this reference is captured.
* When adding a new feature to loaded features, we re-capture
the dup'ed features array and add the short name to a separate
internal cache.
* As long as the dup'ed features array is non-null and matches
the current loaded features array, we know we can safely use the
loaded features index.
* When the dup'ed features array does not match, we clear the
loaded features index and start populating it anew. Since most
typical Ruby code does not modify the loaded features array
directly, this should be rare.

Numbers with and without this change show the performance gained.
The following benchmark populates load path with 1000 entries and
requires the same file 1000 times.

Before:

system ~/projects/jruby $ rvm jruby do jruby bench_loaded_features.rb 1000 1000
  8.110000   3.880000  11.990000 (  9.708000)

After:

system ~/projects/jruby $ jruby bench_loaded_features.rb 1000 1000
  0.990000   0.050000   1.040000 (  0.324000)
daba4d3
@enebo enebo Add helper method c83dd6a
@headius headius Disable tracing during loaded features index check. a93b72d
@headius headius Remove getValues that never ended up being useful. 2c44ffd
@BanzaiMan
Member

Looks good to me!

@headius headius merged commit 01982e3 into master Dec 18, 2012

1 check passed

default The Travis build passed
Details
@LTe LTe referenced this pull request in rubinius/rubinius May 21, 2013
Merged

Add cache for $LOAD_FEATURES and $LOAD_PATH #2353

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment