
FasterPath: Faster Pathname Handling for Ruby Written in Rust - wofo
https://github.com/danielpclark/faster_path
======
ekidd
Articles like this one, and the recent project on libraries like Helix
[http://blog.skylight.io/introducing-
helix/](http://blog.skylight.io/introducing-helix/) make me awfully tempted to
rewrite inner loops in certain production Ruby projects in Rust.

------
bjourne
How on earth can pathname handling be a performance drag? If I read his stats
correctly, then `Pathname#chop_basename` is called 24456 times for one page
load. Something is very fishy about that.

~~~
ape4
Exactly what I was thinking. You look for the last slash and truncate.

~~~
ugexe
This is a naive solution. Try using that on windows.

~~~
ajmurmann
This actually makes me wonder if it would be worthwhile to look for this and
similar issues and remove Windows support from the methods for a custom
implementation. It might shave off some more time.

------
jacquesc
Rails is such a huge community, and Sprockets has to be one of the biggest
pain points for many years.

My solution after years of agony has been to just throw it all out, and use a
diff asset packager underneath rails.

Really happy that people are taking this issue on. Wish I had the time to help
out.

~~~
drewda
Re Sprockets, I found this recent talk at RailsConf about the history,
problems, and future of Sprockets maintenance and development to be an
interesting read: [http://schneems.com/2016/05/31/saving-
sprockets.html](http://schneems.com/2016/05/31/saving-sprockets.html)

------
vvanders

      FasterPath Rust Implementation  Ruby 2.3.1 Implementation  Performance Improvement
      FasterPath.absolute? 	          Pathname#absolute?         1234.6%
    

Nothing like getting 3 orders of magnitude performance improvement.

~~~
InAnEmergency
Ruby's `Pathname#absolute?` is doing a lot more work[1]. I don't know why, but
it is.

If I change it to just check the first character for the file separator, as I
understand FasterPath does, then of course it is faster:

    
    
        Warming up --------------------------------------
                    original     4.109k i/100ms
                      faster   110.202k i/100ms
        Calculating -------------------------------------
                    original     42.645k (± 3.7%) i/s -    213.668k in   5.017595s
                      faster      2.643M (± 4.4%) i/s -     13.224M in   5.013294s
    
        Comparison:
                      faster:  2643274.6 i/s
                    original:    42644.5 i/s - 61.98x slower
    
    

My implementation:

    
    
        class Pathname
          def f_relative?
            @path[0] != File::SEPARATOR
          end
        end
    
    

[1]
[https://github.com/ruby/ruby/blob/68ebbbfebe5b666cf76ab41f1e...](https://github.com/ruby/ruby/blob/68ebbbfebe5b666cf76ab41f1e6191a172d62690/ext/pathname/lib/pathname.rb#L227)

~~~
munificent
That returns a wrong result on Windows paths, and throws an exception on the
empty string.

There are a _ton_ of edge cases in path manipulation code.

~~~
kevincox
I'm pretty sure his implementation works on empty strings because
`str[0].nil?`. So the comparison is false, giving the right (?) answer.

------
idbehold
I'm not at all familiar with programming in Rust or Ruby, but what is the
significance of the string "muffins" on this line?
[https://github.com/danielpclark/faster_path/blob/7033f5a5673...](https://github.com/danielpclark/faster_path/blob/7033f5a567317d96d8a9cff0ade2327ecfb1d32b/src/is_absolute.rs#L17)

Edit: changed link to blob version which will not change line numbers on me.

~~~
nilved
I don't write Rust either, but I might guess that they are trying to unbox a
nullable value that can't be null. They need a default string due to Rusts
strong types even if it's not used.

~~~
gue5t
A more idiomatic way to write the line is:

r_str.chars().next() == Some(MAIN_SEPARATOR)

------
wofo
Not the OP. Just found this very interesting.

