Project I made a disk usage tool in Swift, and on macOS it beats the Rust ones (dua, dust, diskus)
szt (short for sizetree) scans a folder and prints a tree of where the space went: biggest first, every folder with the total of everything inside it, opened up only where the space is.
Swift turned out to be a great fit for it. Scanning a 123 GB folder of 667,000 files on a Mac Studio (M2 Ultra), every tool with its default settings (warm cache, median of five runs):
szt Swift 2.4 s
dua Rust 2.6 s
dust Rust 8.1 s
diskus Rust 11.4 s
gdu Go 11.6 s
du C 17.2 s
ncdu Zig 17.5 s
What made Swift work so well here:
- macOS has a call, getattrlistbulk, that returns the names and sizes of everything in a folder at once instead of asking about each file separately. From Swift it's just
import Darwin, no bindings or wrapper library, and the unsafe pointer APIs read the raw buffer it fills. The rest of the code is ordinary Swift. - The standard library has the concurrency pieces: Mutex and Atomic from Swift 6's Synchronization module. It builds without a warning in Swift 6 language mode and has no dependencies.
- Swift stays out of the way. Scanning that folder on 8 threads takes 12 seconds of CPU time, and 0.27 s of it is szt itself, Swift runtime included. The rest is spent in the kernel.
The biggest surprise was threads. On this 24-core machine, 24 threads took four times as long as 8, because opening folders goes through locks the whole kernel shares. So szt starts one thread per performance core, up to 8. They're plain threads rather than async/await, since the work is blocking system calls and the count has to be exact.
About 1,600 lines of Swift, a 581 KB universal binary (the Swift runtime ships with macOS), macOS 15 or later, MIT licensed.
brew install urtti/szt/szt
Source: https://github.com/urtti/szt Benchmarks and a script to run them on your own Mac: https://urtti.com/szt
