relative-path icon indicating copy to clipboard operation
relative-path copied to clipboard

Optimisation of the Eq/Ord/Hash traits

Open ndmitchell opened this issue 3 years ago • 3 comments

All the Eq/Ord/Hash traits currently operate by iterating the components. Given the underlying String is normalised, why not just forward those traits onto that string? In my benchmarks of inserting these types into a BTreeMap, this changes the benchmark from being mostly spent in the components iterator of RelativePath, to that not showing up at all.

ndmitchell avatar Apr 16 '21 14:04 ndmitchell

Note that this would be a behaviour change as currently foo/ and foo sometimes appear equal. That isn't the behaviour I expect.

ndmitchell avatar Apr 16 '21 15:04 ndmitchell

Hey,

[..] why not just forward those traits onto that string?

So the issue right now is that RelativePath and RelativePathBuf doesn't actually normalize the underlying string. RelativePath in particular can't, because it's a zero-cost wrapper around &str. For RelativePathBuf, see for example the From<String> impl of RelativePathBuf.

Now, I suppose RelativePathBuf could do as much, but that would cause its runtime behavior to deviate from Path and PathBuf. It would also cause a public API break which would require a new major release. I.e. `assert_eq!(RelativePathBuf::from(string.clone()).as_str(), string) would no longer hold.

So while doable, a fair bit of consideration would need to go into it. Thanks for raising the issue though!

udoprog avatar Apr 17 '21 20:04 udoprog

Ah, I had though the underlying representation was normalised. Without that, it is indeed much harder. There still might be a lot of scope for optimisations in these functions though, since in my benchmarks they were pretty slow.

Is the fact that foo and foo/ both appear equal deliberate, or inadvertent?

ndmitchell avatar Apr 17 '21 21:04 ndmitchell