Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/walkdir.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-02-21 03:07:29 +0300
committerAndrew Gallant <jamslam@gmail.com>2018-02-21 03:24:05 +0300
commitddac44a82aeed513f3361ebca4110504e2670d24 (patch)
treee02cb1e94fc4560301c988aaf4730bb2a033a2bc
parente3223962fec481b72a264ab7f41846b47483354b (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.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 423ca1d..9d20478 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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 {