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 8454967562..895e4b1d58 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 ceeba182fe..23e01a7d4d 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)