Como listar diretórios mais rapidamente?

Tenho algumas situações em que preciso listar arquivos recursivamente, mas minhas implementações têm sido lentas. Eu tenho uma estrutura de diretórios com arquivos 92784.find lista os arquivos em menos de 0,5 segundos, mas minha implementação do Haskell é muito mais lenta.

Minha primeira implementação demorou um pouco mais de 9 segundos para ser concluída, a próxima versão um pouco mais de 5 segundos e atualmente estou com menos de dois segundos.

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

O teste ocupa cerca de 100 megabytes de memória (+ RTS-s) e o programa gasta cerca de 40% no GC.

Eu estava pensando em fazer a listagem em uma mônada do WriterT com Sequence como o monóide, para impedir as concats e a criação da lista. É provável que isso ajude? O que mais devo fazer?

Editar: Editei a função para usar o readDirStream, e isso ajuda a manter a memória baixa. Ainda está acontecendo alguma alocação, mas a taxa de produtividade é> 95% agora e é executada em menos de um segundo.

Esta é a versão atual:

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 

questionAnswers(4)

yourAnswerToTheQuestion