dotnet/runtime

File.CopyTo: experiment with truncation and pre-allocation

Open

#64.539 geöffnet am 31. Jan. 2022

Auf GitHub ansehen
 (1 Kommentar) (1 Reaktion) (0 zugewiesene Personen)C# (5.445 Forks)batch import
area-System.IOhelp wantedtenet-performance

Repository-Metriken

Stars
 (17.886 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 12T 11h) (661 gemergte PRs in 30 T)

Beschreibung

In a very small experiment that I've performed in #61676 I've observed up to x2 perf gains that were rather specific to ext4 File System (which is the default on Linux?).

As pointed by @tmds in https://github.com/dotnet/runtime/pull/61676#issuecomment-971433175 large part of the gains was simply undoing the cost of ftruncate.

For File.Copy($srcPath, $destPath, overwrite: true), ftruncate is currently always performed before copying the file. It's not obvious, as it's a side effect of using FileMode.Create here:

https://github.com/dotnet/runtime/blob/c091dc3b634d47b02f2041542a93fd8870ed1ba8/src/libraries/System.Private.CoreLib/src/System/IO/FileSystem.Unix.cs#L24

the actual sys-call is performed here:

https://github.com/dotnet/runtime/blob/c091dc3b634d47b02f2041542a93fd8870ed1ba8/src/libraries/System.Private.CoreLib/src/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs#L410-L414

It would be great to dig in more into that and see if we could make File.Copy($srcPath, $destPath, overwrite: true) faster by delaying the truncation to happen after file copying ends. I've done some quick experiment and I've observed up to 5x gain for large files on ext4. Another aspect of the experiment would be to measure the gains of file preallocation for cases when new files are being created.

The person who is willing to work on this issue should measure the performance using both ext4 and btrfs file systems and ensure that whatever changes we made don't regress any of the file systems.

Contributor Guide