haskell / haskell/directory

`getModificationTime` is about 10x slower on windows compared to linux

Open
#204 1 comment 0 reactions 0 assignees View on GitHub
type: (5) investigation
Dominant language
Haskell
Stars
65
Forks
52
PR merge metrics
No merged PRs in 30d

Description

```
#!/usr/bin/env -S cabal run
{- cabal:
build-depends: base >=4.17 && <5
, directory >=1.3.8
, filepath >=1.4.100
, time
default-language: GHC2021
ghc-options: -O2
-}

import System.OsPath
import System.Directory.OsPath (getModificationTime)
import Control.Monad

main :: IO ()
main = do
let rel_path = unsafeEncodeUtf "Main.hs"

replicateM_ 1000000 (getModificationTime rel_path)
```

When I run this benchmark on linux, I get

```
447,660,936 bytes allocated in the heap
14,656 bytes copied during GC
35,984 bytes maximum residency (1 sample(s))
29,552 bytes maximum slop
7 MiB total memory in use (0 MiB lost due to fragmentation)

Tot time (elapsed) Avg pause Max pause
Gen 0 107 colls, 0 par 0.001s 0.001s 0.0000s 0.0000s
Gen 1 1 colls, 0 par 0.000s 0.000s 0.0001s 0.0001s

INIT time 0.000s ( 0.000s elapsed)
MUT time 0.584s ( 0.585s elapsed)
GC time 0.001s ( 0.001s elapsed)
EXIT time 0.000s ( 0.000s elapsed)
Total time 0.585s ( 0.586s elapsed)

%GC time 0.0% (0.0% elapsed)

Alloc rate 766,951,617 bytes per MUT second

Productivity 99.7% of total user, 99.7% of total elapsed
```

on windows, my colleague ran the program, and it allocates about 10x more.

```
44,760,076,432 bytes allocated in the heap
7,301,816 bytes copied during GC
34,928 bytes maximum residency (2 sample(s))
26,928 bytes maximum slop
6 MiB total memory in use (0 MiB lost due to fragmentation)

Tot time (elapsed) Avg pause Max pause
Gen 0 10644 colls, 0 par 0.016s 0.056s 0.0000s 0.0001s
Gen 1 2 colls, 0 par 0.000s 0.001s 0.0005s 0.0008s

INIT time 0.000s ( 0.000s elapsed)
MUT time 4.281s ( 18.487s elapsed)
GC time 0.016s ( 0.057s elapsed)
EXIT time 0.000s ( 0.000s elapsed)
Total time 4.297s ( 18.544s elapsed)

%GC time 0.0% (0.0% elapsed)

Alloc rate 10,454,908,363 bytes per MUT second

Productivity 99.6% of total user, 99.7% of total elapsed
```

It seems that in the windows code paths there is much more file path manipulation happening which converts from `OsPath` to `FilePath` and back again.

Contributor guide

Open the contributing guide

Research direction

Start with the inline Cabal benchmark and the System.Directory.OsPath getModificationTime entry point, then compare the Windows and Linux paths it exercises. Investigate the reported OsPath-to-FilePath conversions and rerun the million-call benchmark on Windows; done means the Windows path avoids the excess allocation while preserving modification-time behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
operating-systems, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.