Wie können Verzeichnisse schneller aufgelistet werden?

Ich habe einige Situationen, in denen ich Dateien rekursiv auflisten muss, aber meine Implementierungen waren langsam. Ich habe eine Verzeichnisstruktur mit 92784 Dateien.find listet die Dateien in weniger als 0,5 Sekunden auf, aber meine Haskell-Implementierung ist viel langsamer.

Meine erste Implementierung dauerte etwas mehr als 9 Sekunden, die nächste Version etwas mehr als 5 Sekunden und ich bin derzeit auf etwas weniger als zwei Sekunden reduziert.

listFilesR :: FilePath -> IO [FilePath]
listFilesR path = let
    isDODD "." = False
    isDODD ".." = False
    isDODD _ = True

    in do
        allfiles <- getDirectoryContents path
    dirs <- forM allfiles $ \d ->
      if isDODD d then
        do let p = path </> d
           isDir <- doesDirectoryExist p
           if isDir then listFilesR p else return [d]
        else return []
    return $ concat dirs

Der Test benötigt ungefähr 100 Megabyte Speicher (+ RTS -s) und das Programm gibt ungefähr 40% für GC aus.

Ich habe darüber nachgedacht, die Auflistung in einer WriterT-Monade mit Sequence als Monoid vorzunehmen, um die Erstellung von Concats und Listen zu verhindern. Ist es wahrscheinlich, dass dies hilft? Was soll ich sonst machen

Bearbeiten Ich habe die Funktion so bearbeitet, dass sie readDirStream verwendet, und sie hilft dabei, den Speicher niedrig zu halten. Es ist noch eine gewisse Zuweisung im Gange, aber die Produktivitätsrate liegt jetzt bei> 95% und dauert weniger als eine Sekunde.

Dies ist die aktuelle Version:

list path = do
  de <- openDirStream path
  readDirStream de >>= go de
  closeDirStream de
  where
    go d [] = return ()
    go d "." = readDirStream d >>= go d
    go d ".." = readDirStream d >>= go d
    go d x = let newpath = path </> x
         in do
          e <- doesDirectoryExist newpath
          if e 
        then
          list newpath >> readDirStream d >>= go d
        else putStrLn newpath >> readDirStream d >>= go d 

Antworten auf die Frage(8)

Ihre Antwort auf die Frage