dirEntries removes entire branches of empty directories

kdevel kdevel at vogtner.de
Fri Nov 11 13:13:12 UTC 2022


On Thursday, 10 November 2022 at 21:27:28 UTC, Ali Çehreli wrote:
> On 11/9/22 12:06, Ali Çehreli wrote:
>
> > I am using its sibling 'ftw'
>
> Now that we know that dirEntries works properly, I decided not 
> to use ftw.
>
> However, ftw performs about twice as fast as dirEntries 
> (despite some common code in the implementation below).

dmd -O compiled patched (see below!) version applied to /usr/bin 
on my desktop
yields:

ftw       : 363 ms, 750 ÎŒs, and 5 [*]
dirEntries: 18 secs, 831 ms, 738 ÎŒs, and 3 [*]

(* = offending units removed)

> [...]
>     foreach (entry; dirEntries(root, SpanMode.depth)) {
>         if (entry.isDir) {
>             dirs ~= entry;
>
>         } else {
>             entries ~= DirectoryEntry(entry, entry.getSize);
>         }

strace reports that entry.getSize invokes stat on the file a 
second time. Isn't
the stat buf saved in the entry?

This also gives rise for a complication with symlinks pointing to 
the directory
which contain them:

    $ pwd
    /tmp/k/sub
    $ ln -s . foo
    $ ../direntrybenchmark .
    
std.file.FileException at 8[...]/linux/bin64/../../src/phobos/std/file.d(1150): ./foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo/foo: Too many levels of symbolic links
    [...]

> [...]
>     if (args.length != 2) {
>         stderr.writefln!"Please provide the directory to 
> walk:\n\n  %s <directory>\n"
>             (args[0].baseName);
>         return 1;
>     }
>
>     const dir = buildNormalizedPath("/home/ali/dlang");

diff --git a/direntrybenchmark.d b/direntrybenchmark.d
index 661df51..a9a5616 100644
--- a/direntrybenchmark.d
+++ b/direntrybenchmark.d
@@ -102,8 +102,9 @@ WalkResult directoryWalk_dirEntries(string 
root) {
          if (entry.isDir) {
              dirs ~= entry;

-        } else {
-            entries ~= DirectoryEntry(entry, entry.getSize);
+        }
+        else {
+            entries ~= DirectoryEntry(entry, 0);
          }
      }

@@ -133,7 +134,7 @@ int main(string[] args) {
          return 1;
      }

-    const dir = buildNormalizedPath("/home/ali/dlang");
+    const dir = buildNormalizedPath(args[1]);

      auto timings = benchmark!({ directoryWalk_ftw(dir); },
                                { directoryWalk_dirEntries(dir); 
})(10);





More information about the Digitalmars-d-learn mailing list