From 1adebdc7676e44c91daeee24745a63c2019e2ec3 Mon Sep 17 00:00:00 2001 From: def Date: Tue, 24 Feb 2015 16:37:54 +0100 Subject: [PATCH] Speed up walkDir significantly We only know that this works on Linux and Mac OS X, so other systems use the POSIX conforming version still. This removed the lstat call, which is especially expensive on NFS filesystems for me. --- lib/posix/posix.nim | 13 +++++++++++++ lib/pure/os.nim | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index 845496756..895e4b1d5 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -70,6 +70,16 @@ const STDIN_FILENO* = 0 ## File number of stdin; STDOUT_FILENO* = 1 ## File number of stdout; + DT_UNKNOWN* = 0 + DT_FIFO* = 1 + DT_CHR* = 2 + DT_DIR* = 4 + DT_BLK* = 6 + DT_REG* = 8 + DT_LNK* = 10 + DT_SOCK* = 12 + DT_WHT* = 14 + type TDIR* {.importc: "DIR", header: "", incompleteStruct.} = object @@ -84,6 +94,9 @@ type Tdirent* {.importc: "struct dirent", header: "", final, pure.} = object ## dirent_t struct d_ino*: Tino ## File serial number. + d_off*: TOff + d_reclen*: cshort + d_type*: int8 d_name*: array [0..255, char] ## Name of entry. Tflock* {.importc: "struct flock", final, pure, diff --git a/lib/pure/os.nim b/lib/pure/os.nim index ceeba182f..23e01a7d4 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1299,10 +1299,14 @@ iterator walkDir*(dir: string): tuple[kind: PathComponent, path: string] {. if y != "." and y != "..": var s: TStat y = dir / y - if lstat(y, s) < 0'i32: break var k = pcFile - if S_ISDIR(s.st_mode): k = pcDir - if S_ISLNK(s.st_mode): k = succ(k) + when defined(linux) or defined(macosx): + if x.d_type == DT_DIR: k = pcDir + if x.d_type == DT_LNK: k = succ(k) + else: + if lstat(y, s) < 0'i32: break + if S_ISDIR(s.st_mode): k = pcDir + if S_ISLNK(s.st_mode): k = succ(k) yield (k, y) discard closedir(d)