diff options
author | Andrew Gallant <jamslam@gmail.com> | 2018-02-21 03:07:29 +0300 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2018-02-21 03:24:05 +0300 |
commit | ddac44a82aeed513f3361ebca4110504e2670d24 (patch) | |
tree | e02cb1e94fc4560301c988aaf4730bb2a033a2bc | |
parent | e3223962fec481b72a264ab7f41846b47483354b (diff) |
performance: fix regression
This commit fixes a performance regression introduced in commit 0f4441,
which aimed to fix OneDrive traversals. In particular, we added an
additional stat call to every directory entry, which can be quite
disastrous for performance. We fix this by being more fastidious about
reusing the Metadata that comes from fs::DirEntry, which is, conveniently,
cheap to acquire specifically on Windows.
The performance regression was reported against ripgrep:
https://github.com/BurntSushi/ripgrep/issues/820
-rw-r--r-- | src/lib.rs | 16 |
1 files changed, 15 insertions, 1 deletions
@@ -1005,6 +1005,20 @@ impl DirEntry { /// [`std::fs::metadata`]: https://doc.rust-lang.org/std/fs/fn.metadata.html /// [`std::fs::symlink_metadata`]: https://doc.rust-lang.org/stable/std/fs/fn.symlink_metadata.html pub fn metadata(&self) -> Result<fs::Metadata> { + self.metadata_internal() + } + + #[cfg(windows)] + fn metadata_internal(&self) -> Result<fs::Metadata> { + if self.follow_link { + fs::metadata(&self.path) + } else { + Ok(self.metadata.clone()) + }.map_err(|err| Error::from_entry(self, err)) + } + + #[cfg(not(windows))] + fn metadata_internal(&self) -> Result<fs::Metadata> { if self.follow_link { fs::metadata(&self.path) } else { @@ -1064,7 +1078,7 @@ impl DirEntry { let ty = ent.file_type().map_err(|err| { Error::from_path(depth, path.clone(), err) })?; - let md = fs::metadata(&path).map_err(|err| { + let md = ent.metadata().map_err(|err| { Error::from_path(depth, path.clone(), err) })?; Ok(DirEntry { |