Feature #5767
closedCache expanded_load_path to reduce startup time
Description
This patch add caching of expanded load path.
It reduces rails startup time by 33%
(patch against 1.9.3-p0 and simple performance test is here https://gist.github.com/1480404 )
Files
Updated by now (Nikolai Weibull) almost 13 years ago
On Thu, Dec 15, 2011 at 10:18, Yura Sokolov funny.falcon@gmail.com wrote:
Issue #5767 has been reported by Yura Sokolov.
Feature #5767: Cache expanded_load_path to reduce startup time
http://redmine.ruby-lang.org/issues/5767Author: Yura Sokolov
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This patch add caching of expanded load path.
It reduces rails startup time by 33%
(patch against 1.9.3-p0 and simple performance test is here https://gist.github.com/1480404 )
Is it only me, or is treating $LOAD_PATH like an array hurting
possible optimizations? I mean, how sane is it to allow
$LOAD_PATH.map!{ … }?
Updated by shyouhei (Shyouhei Urabe) almost 13 years ago
Nikolai Weibull wrote:
On Thu, Dec 15, 2011 at 10:18, Yura Sokolov funny.falcon@gmail.com wrote:
Issue #5767 has been reported by Yura Sokolov.
Feature #5767: Cache expanded_load_path to reduce startup time
http://redmine.ruby-lang.org/issues/5767Author: Yura Sokolov
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This patch add caching of expanded load path.
It reduces rails startup time by 33%
(patch against 1.9.3-p0 and simple performance test is here https://gist.github.com/1480404 )Is it only me, or is treating $LOAD_PATH like an array hurting
possible optimizations? I mean, how sane is it to allow
$LOAD_PATH.map!{ … }?
$LOAD_PATH determines the order to search required files. At least it must be ordered linearly.
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
Nikolai Weibull wrote:
Is it only me, or is treating $LOAD_PATH like an array hurting
possible optimizations? I mean, how sane is it to allow
$LOAD_PATH.map!{ … }?
I think, you right. $LOAD_PATH and $LOADED_FEATURES should be restricted.
But currently they not.
When I trying to improve $LOADED_FEATURES at #5427, I remove dangerous methods.
In this patch, it just invalidates cache when complex self modifying method is called,
and keeps cache valid in case of simple methods, like push
, pop
, <<
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
Cosmetic update to patch: more atomic cache access.
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
There is report about 47% startup time reduction https://gist.github.com/1480404#gistcomment-69769
Updated by luislavena (Luis Lavena) almost 13 years ago
For those interested here are some raw performance numbers and comparison between default (no patch) and other patches combined:
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
I removed messing with file.c.
Instead rb_get_load_path returns expanded paths when optimization is enabled.
I have updated pull request, so that it contains one commit.
https://github.com/ruby/ruby/pull/68.patch
https://github.com/ruby/ruby/pull/68
Updated by funny_falcon (Yura Sokolov) almost 13 years ago
https://gist.github.com/1688857
Most of success of that gist is cause of this issue.
Cites from comments:
Thanks for sharing that. Indeed the speed increase is quite impressive! I've tested the time it take to run some rspec test before and after. Here are the results:
Before: Finished in 402.79 seconds (3521 examples, 3 failures, 39 pending)
After: Finished in 222,82 seconds (3521 examples, 3 failures, 39 pending). WOOW!
Obligatory benchmarks:
Test Suite on 1.9.3-p0 proper : 2m06s
Rails boot time : 9.1s
Suite on 1.9.3-p0-perf : 1m32s
Rails boot time : 6.5s
Not bad.
$ time rake
before:
real 0m37.919s
user 0m6.474s
sys 0m0.919s
after:
real 0m34.236s
user 0m3.367s
sys 0m0.848s
$ time rails runner "Time.now"
before:
real 0m4.589s
user 0m3.871s
sys 0m0.629s
after:
real 0m2.437s
user 0m1.889s
sys 0m0.534s
5.5 secs instead of 8.8 secs for rails runner "puts "omfg""
rspec . 15.1 seconds instead of 18.2 seconds
One of my Rails apps, boot time (measured with ./bin/rails runner 'puts 3'
1.9.3-perf: 5.1 seconds
1.9.3-p0: 8.1 seconds
1.9.2-p290: 18.2 seconds
My rake parallel:spec went down from 68 to 38sec!!!!!!!!!! That's 44% cut off! Fantastic! THANK YOU!
API spec tests ~30% faster!
time bundle exec rake environment
Before:
14.60s user 1.26s system 100% cpu 15.861 total
After:
5.11s user 1.10s system 99% cpu 6.212 total
60.8% speedup!!!!!!
Updated by mame (Yusuke Endoh) over 12 years ago
- Status changed from Open to Assigned
- Assignee set to nobu (Nobuyoshi Nakada)
Sorry I don't catch up the discussion.
What's the status?
The proposal is COMPLETELY compatible?
It may be helpful for me to create a short summary of the proposal and discussion.
I tentatively assign this to nobu.
Any other committer is interested in this issue?
--
Yusuke Endoh mame@tsg.ne.jp
Updated by funny_falcon (Yura Sokolov) over 12 years ago
The proposal is COMPLETELY compatible?
This proposal is completely compatible, since LOAD_PATH remains the same array, methods are overridden only to keep cache in sync.
Proposal is about keeping result of expanding LOAD_PATH entries in a 'invisible' cache.
This cache is lazy invalidated on changing directory and filesystem encoding, so that
the whole semantic of LOAD_PATH remains the same.
Methods of LOAD_PATH overridden to keep cache in sync, so that there is no need to expand
all paths again if entries were only appended to any side of LOAD_PATH, or removed from any side.
It saves up to 35% of big application's startup time and still brings slight improvement
for small scripts.
(Only Jeremy Evan's sequel use self crafted super fast load system which does not gain improvement from this patch)
I didn't check it against current trunk, but believe there could not be big problems.
There is still small room for improvement this patch: make chached expanded paths class to be
subclass of String, and then test against it in a file_expand_path, so that to not expand it
twice in calls from rb_find_file_ext_safe and rb_find_file_safe.
Yura aka funny_falcon
Updated by trans (Thomas Sawyer) over 12 years ago
Does this have any effect on https://bugs.ruby-lang.org/issues/4969 (scroll down to post #7).
Updated by funny_falcon (Yura Sokolov) over 12 years ago
Does this have any effect on https://bugs.ruby-lang.org/issues/4969 (scroll down to post #7).
Thomas Sawyer, this proposal has no any effect on #4969 because it doesn't change require semantic
in any way. It only improve performance.
I leave my comment at #4969 and I still take that point: #4969 is about making game more tangled but easier to win instead of playing by the rules, imho.
Updated by h.shirosaki (Hiroshi Shirosaki) almost 12 years ago
- Status changed from Assigned to Closed
Fixed by #7158.