[#46918] [ruby-trunk - Bug #6820][Open] Time#to_s on NEWS — "no6v (Nobuhiro IMAI)" <nov@...>
8 messages
2012/08/01
[#46922] [ruby-trunk - Bug #6822][Open] Race Condition with Fiber and Process — "MartinBosslet (Martin Bosslet)" <Martin.Bosslet@...>
8 messages
2012/08/02
[#46973] [ruby-trunk - Bug #6829][Open] Failure using Win32ole (happens in 1.8.7 and 1.9 — "mvanduyn (Mitch VanDuyn)" <mitch@...>
6 messages
2012/08/03
[#46974] [ruby-trunk - Bug #6830][Assigned] test failure test_constants(OpenSSL::TestConfig) [/ruby/test/openssl/test_config.rb:27] on Mac + homebrew — "kosaki (Motohiro KOSAKI)" <kosaki.motohiro@...>
17 messages
2012/08/04
[#46978] [ruby-trunk - Bug #6832][Open] Module#instance_method and Module#method_defined? act inconsistently w.r.t #respond_to_missing? — "myronmarston (Myron Marston)" <myron.marston@...>
6 messages
2012/08/04
[#46996] [ruby-trunk - Bug #6836][Assigned] Improve File.expand_path performance in Windows — "luislavena (Luis Lavena)" <luislavena@...>
15 messages
2012/08/04
[#47021] [ruby-trunk - Bug #6836] Improve File.expand_path performance in Windows
— "luislavena (Luis Lavena)" <luislavena@...>
2012/08/06
[#47045] [ruby-trunk - Bug #6836] Improve File.expand_path performance in Windows
— "h.shirosaki (Hiroshi Shirosaki)" <h.shirosaki@...>
2012/08/07
[#47036] [ruby-trunk - Feature #6841][Open] Shorthand for Assigning Return Value of Method to Self — "wardrop (Tom Wardrop)" <tom@...>
18 messages
2012/08/07
[#52968] [ruby-trunk - Feature #6841] Shorthand for Assigning Return Value of Method to Self
— "wardrop (Tom Wardrop)" <tom@...>
2013/02/27
[#47050] [ruby-trunk - Feature #6842][Open] Add Optional Arguments to String#strip — "wardrop (Tom Wardrop)" <tom@...>
10 messages
2012/08/07
[#47091] [ruby-trunk - Feature #6847][Open] Hash#extract — "citizen428 (Michael Kohl)" <citizen428@...>
10 messages
2012/08/09
[#47094] [ruby-trunk - Bug #6849][Open] Psych.load_file throws TypeError for empty file — "BrandonMathis (Brandon Mathis)" <BeMathis@...>
4 messages
2012/08/09
[#47103] [ruby-trunk - Bug #6851][Open] Result of File.stat("c:/...") is different from 1.9.3 — "phasis68 (Heesob Park)" <phasis@...>
8 messages
2012/08/10
[#47108] [ruby-trunk - Feature #6852][Open] [].transpose should behave specially — "boris_stitnicky (Boris Stitnicky)" <boris@...>
13 messages
2012/08/10
[#47138] [ruby-trunk - Bug #6861][Open] ERB::Util.escape_html is not escaping single quotes — "spastorino (Santiago Pastorino)" <santiago@...>
14 messages
2012/08/12
[#47199] [ruby-trunk - Bug #6872][Open] Array does not specify how it determines uniqueness of values — "agrimm (Andrew Grimm)" <andrew.j.grimm@...>
8 messages
2012/08/15
[#47243] [ruby-trunk - Feature #6895][Open] TracePoint API — "ko1 (Koichi Sasada)" <redmine@...>
27 messages
2012/08/20
[#47254] [ruby-trunk - Feature #6895] TracePoint API
— "trans (Thomas Sawyer)" <transfire@...>
2012/08/20
[#47257] Re: [ruby-trunk - Feature #6895] TracePoint API
— SASADA Koichi <ko1@...>
2012/08/21
(2012/08/21 6:11), trans (Thomas Sawyer) wrote:
[#47277] [ruby-trunk - Feature #6895] TracePoint API
— "trans (Thomas Sawyer)" <transfire@...>
2012/08/22
[#47287] [ruby-trunk - Feature #6910][Assigned] Loading syck's broken yaml with psych — "naruse (Yui NARUSE)" <naruse@...>
5 messages
2012/08/23
[#47309] [ruby-trunk - Bug #6929][Open] Documentation for Ripper — "zzak (Zachary Scott)" <zachary@...>
16 messages
2012/08/25
[#47322] Re: [ruby-cvs:43987] luislavena:r36811 (trunk): Improve require/File.expand_path performance on Windows — Urabe Shyouhei <shyouhei@...>
Hello Luis,
4 messages
2012/08/27
[#47345] [ruby-trunk - Feature #6946][Open] FIPS support? — "vo.x (Vit Ondruch)" <v.ondruch@...>
35 messages
2012/08/28
[#48231] [ruby-trunk - Feature #6946] FIPS support?
— "ko1 (Koichi Sasada)" <redmine@...>
2012/10/25
[#51002] [ruby-trunk - Feature #6946] FIPS support?
— "MartinBosslet (Martin Bosslet)" <Martin.Bosslet@...>
2012/12/20
[#51004] Re: [ruby-trunk - Feature #6946] FIPS support?
— SASADA Koichi <ko1@...>
2012/12/20
After that, I got the following error.
[#51006] Re: [ruby-trunk - Feature #6946] FIPS support?
— Martin Bo煬et <martin.bosslet@...>
2012/12/20
2012/12/20 SASADA Koichi <ko1@atdot.net>
[#47350] No tag for 1.8.7p370 on Github? — Charles Oliver Nutter <headius@...>
I was about to update JRuby's 1.8.7 stdlib, but there's no tag for
3 messages
2012/08/28
[#47367] [ruby-trunk - Bug #6950][Open] ruby-mode: comint-previous-input does not work — "cinsk (Seong-Kook Shin)" <cinsky@...>
6 messages
2012/08/30
[#47369] [ruby-trunk - Bug #6950] ruby-mode: comint-previous-input does not work
— "drbrain (Eric Hodel)" <drbrain@...7.net>
2012/08/30
[ruby-core:47294] [ruby-trunk - Bug #6836] Improve File.expand_path performance in Windows
From:
"luislavena (Luis Lavena)" <luislavena@...>
Date:
2012-08-23 04:45:59 UTC
List:
ruby-core #47294
Issue #6836 has been updated by luislavena (Luis Lavena).
File improve-require-and-file-expand_path-windows.v2.diff added
=begin
usa (Usaku NAKAMURA) wrote:
> Hello,
>
> If the performance problem is in 'require' and 'load', change only them
> and be stayed File.expand_path the same behavior.
> Can't do so?
Thank you Usa for your feedback.
Based on Hiroshi experiment I've worked in an updated patch (attached)
This new patch shows the same performance boost on (({require})) without breaking backward compatibility of (({File.expand_path}))
trunk:
ruby 2.0.0dev (2012-08-23 trunk 36786) [i386-mingw32]
Rehearsal ------------------------------------------------------
core_require_empty 1.264000 3.151000 4.415000 ( 4.446254)
--------------------------------------------- total: 4.415000sec
user system total real
core_require_empty 1.154000 3.229000 4.383000 ( 4.432253)
Rehearsal -------------------------------------------------------
core_require_nested 1.248000 3.447000 4.695000 ( 4.707269)
---------------------------------------------- total: 4.695000sec
user system total real
core_require_nested 1.467000 3.214000 4.681000 ( 4.699268)
patched:
ruby 2.0.0dev (2012-08-23 trunk 36786) [i386-mingw32]
Rehearsal ------------------------------------------------------
core_require_empty 0.593000 0.936000 1.529000 ( 1.595091)
--------------------------------------------- total: 1.529000sec
user system total real
core_require_empty 0.624000 0.936000 1.560000 ( 1.577090)
ruby 2.0.0dev (2012-08-23 trunk 36786) [i386-mingw32]
Rehearsal -------------------------------------------------------
core_require_nested 0.843000 0.998000 1.841000 ( 1.855106)
---------------------------------------------- total: 1.841000sec
user system total real
core_require_nested 0.764000 1.061000 1.825000 ( 1.838106)
This also improves Rails and Rake startup time
From (trunk, mid-size Rails app):
V:\enki>timer ruby script\rails runner -e production "p $LOADED_FEATURES.size"
1135
real 22.710
system 11.013
user 11.575
V:\enki>timer rake -T
...
real 8.868
system 0.031
user 0.000
To (patched):
V:\enki>timer ruby script\rails runner -e production "0"
real 10.735
system 1.716
user 8.923
V:\enki>timer rake -T
...
real 3.068
system 0.015
user 0.015
Updated the Gist that contains the benchmark and patch:
https://gist.github.com/3242245
Considering the size of the patch and to make it more easy to review, I've pushed to my fork on GitHub the individual commits and explanation of each change here:
https://github.com/luislavena/ruby/compare/improve-require-and-file-expand_path
Looking forward for your comments and feedback.
Thank you for your time.
=end
----------------------------------------
Bug #6836: Improve File.expand_path performance in Windows
https://bugs.ruby-lang.org/issues/6836#change-28999
Author: luislavena (Luis Lavena)
Status: Assigned
Priority: Normal
Assignee: nobu (Nobuyoshi Nakada)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-08-04 trunk 36616) [i386-mingw32]
=begin
(original write up in markdown here: https://gist.github.com/3242245)
== Background
While investigating the performance issues of (({File.expand_path})) on Windows,
Usaku Nakamura and Nobuyoshi Nakada on [ruby-core:39504] pointed out that
due security concerns, accessing files on Windows required normalized paths.
This was covered in the security update of March 2008, WEBrick file-access
vulnerability [1].
After closer inspection of WEBrick code (mentioned by the security update),
I noticed it uses (({File.expand_path})) to perform the heavy lifting of path
normalization in the request.
The code around this can be inspected in (({prevent_directory_traversal}))[2]
and (({shift_path_info}))[3] methods.
This approach performs a hit into the filesystem, contrary to its
implementation in any other operating system.
(({File.expand_path})) is heavily used by (({require})), which result in slow
application startup, depending on the application size or number of gems it
depends on.
Stepping back for a second, we can see that the security issue is around
WEBrick and the way it determines (({path_info})) absoluteness.
It is also clear that to solve WEBrick security issue, a tax has been applied
to the entire Ruby ecosystem, penalizing startup performance.
With Hiroshi Shirosaki's help, we worked on a patch that:
* Limit filesystem hit only to WEBrick, using Windows' GetLongPathName [4].
* Use a Windows-specific API to normalize paths
* Improve encoding support.
What started as an experiment named Fenix [5] has shown great results on a
variety of systems.
This patch has been integrated in TheCodeShop [6] releases of Ruby 1.9.3 and
tested by Ruby-Core developers Hiroshi Shirosaki and myself.
== Performance
To demonstrate the benefits of this patch, I've used measurements [7] project
and both (({core_require_empty})) and (({core_require_nested})) workloads,
obtaining the following results:
ruby 2.0.0dev (2012-08-03 trunk 36611) [i386-mingw32]
Rehearsal ------------------------------------------------------
core_require_empty 1.186000 3.385000 4.571000 ( 4.676267)
--------------------------------------------- total: 4.571000sec
user system total real
core_require_empty 1.217000 3.385000 4.602000 ( 4.643266)
Rehearsal -------------------------------------------------------
core_require_nested 1.514000 3.760000 5.274000 ( 5.305303)
---------------------------------------------- total: 5.274000sec
user system total real
core_require_nested 1.466000 3.713000 5.179000 ( 5.233300)
And with patch applied:
ruby 2.0.0dev (2012-08-03 trunk 36611) [i386-mingw32]
Rehearsal ------------------------------------------------------
core_require_empty 0.765000 1.077000 1.842000 ( 1.887603)
--------------------------------------------- total: 1.842000sec
user system total real
core_require_empty 0.717000 1.123000 1.840000 ( 1.887603)
Rehearsal -------------------------------------------------------
core_require_nested 0.717000 1.670000 2.387000 ( 2.480405)
---------------------------------------------- total: 2.387000sec
user system total real
core_require_nested 0.890000 1.528000 2.418000 ( 2.496004)
Benchmarks were performed all on the same hardware and OS:
* CPU: Core 2 Duo T7500 @ 2.20Ghz
* RAM: 4GB
* HDD: 1.5GB RAMdisk (ImDisk)
* OS: Windows 7 Ultimate x64
All tests associated (both File and WEBrick ones) pass.
Additional tests that exercise specific aspects of new function were added.
Patch has been tested also against:
* Visual Studio build of Ruby
* Ubuntu 12.04
* Mac OSX
And the patch didn't affect either build or tests of it.
=== Real life impact: Rails
The biggest Ruby project affected by this is Rails applications.
An empty Rails application on startup requires more than 700 files from
different gems:
V:\emptyapp>ruby script\rails runner -e production "p $LOADED_FEATURES.size"
772
When benchmark startup using w32time [8]:
V:\emptyapp>timer ruby script\rails runner -e production "0"
real 7.285
system 4.539
user 2.683
And patched Ruby:
V:\emptyapp>timer ruby script\rails runner -e production "0"
real 2.620
system 0.873
user 1.700
(best result taken from several warm ups).
Now, a mid-sized application like Enki [9] which loads 1146 files in
production mode, result in:
V:\enki>timer ruby script\rails runner -e production "p $LOADED_FEATURES.size"
1146
real 22.620
system 11.497
user 11.076
Almost ((*23 seconds*)), compared to patched version:
V:\enki>timer ruby script\rails runner -e production "0"
real 11.013
system 1.981
user 8.938
This change also improves performance of (({rake})) inside Rails, from:
V:\enki>timer rake -T
...
real 8.689
system 0.015
user 0.000
To:
V:\enki>timer rake -T
...
real 3.307
system 0.000
user 0.031
Making normal operations more accessible.
Looking forward for your thoughts on these changes.
Thank you.
[1] http://www.ruby-lang.org/en/news/2008/03/03/webrick-file-access-vulnerability/
[2] https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpservlet/filehandler.rb#L242-263
[3] https://github.com/ruby/ruby/blob/trunk/lib/webrick/httpservlet/filehandler.rb#L330-337
[4] http://msdn.microsoft.com/en-us/library/windows/desktop/aa364980.aspx
[5] https://github.com/luislavena/fenix
[6] http://thecodeshop.github.com/
[7] https://github.com/jonforums/measurements
[8] https://github.com/thecodeshop/w32time
[9] https://github.com/xaviershay/enki
=end
--
http://bugs.ruby-lang.org/