-
Notifications
You must be signed in to change notification settings - Fork 0
Home
The win32-xpath library is a custom version of the File.expand_path
method for Windows.
I wrote this because I noticed that the tests for File.expand_path
from my custom test suite were rather slow. When I realized that it was because the underlying code was poor, I decided to rewrite it. I thought this code had been revamped by Luis Lavena once already, but it's not clear to me if his code was simply never integrated or if he just did a crappy job. Either way, the current source code isn't good.
I also decided that it would be nice to allow "~user" notation, which this library supports.
This code is much faster than the MRI source code. Here are some benchmarks of 100k iterations on Windows 7 using Ruby 2.2.0 that was built with the MS Visual Studio 2013 compiler:
Old File.expand_path
user system total real
expand_path('foo/bar') 0.780000 1.404000 2.184000 ( 2.173918)
expand_path('C:/foo/bar') 0.686000 1.654000 2.340000 ( 2.350356)
expand_path('//foo/bar') 1.108000 27.768000 28.876000 ( 31.596080)
expand_path('foo//bar///') 0.764000 1.404000 2.168000 ( 2.168984)
expand_path('~') 1.233000 2.917000 4.150000 ( 4.152460)
expand_path('') 1.014000 3.495000 4.509000 ( 4.507877)
expand_path('', '~') 1.201000 2.901000 4.102000 ( 4.137849)
New File.expand_path
user system total real
expand_path('foo/bar') 0.530000 0.000000 0.530000 ( 0.531334)
expand_path('C:/foo/bar') 0.343000 0.016000 0.359000 ( 0.372399)
expand_path('//foo/bar') 0.359000 0.031000 0.390000 ( 0.386417)
expand_path('foo//bar///') 0.608000 0.016000 0.624000 ( 0.608276)
expand_path('~') 0.500000 0.109000 0.609000 ( 0.623673)
expand_path('') 0.343000 0.047000 0.390000 ( 0.394709)
expand_path('', '~') 0.671000 0.125000 0.796000 ( 0.817625)
As you can see, it's about 5x faster than MRI. Note that there's a pathological case in MRI when calling File.expand_path on a UNC root path. In that particular case, my code is 100x faster.
This code is still about 2x faster than JRuby, too.
As mentioned in the README, I don't support $DATA mangling, and I don't explicitly support drive-current paths. It is extremely unlikely that you will be affected by either of these things. And no, those things don't explain the 5x performance difference.
Update 1: As of Ruby 2.5, it seems their benchmarks have improved to parity in the case of expand_path('~')
and expand_path('', '~')
, but this library is still roughly 5x faster in other cases. And their pathological slowdown for UNC paths still exists.
Update 2: Regarding the pathological slowdown on UNC paths, I have reported it and it has been fixed. You can see details at https://bugs.ruby-lang.org/issues/15633.