Directly read macOS theme preference instead of using defaults by BlackHoleFox · Pull Request #2442 · sharkdp/bat (original) (raw)
Follows on #2197 by improving the implementation of macos_dark_mode_active
.
For reference there are a lot of ways to read preferences on macOS. Here's the 4 I know of:
defaults
CLI- NSUserDefaults via Objective-C
- CFPreferences via CoreFoundation (C/C++)
- Directly reading and parsing the file from disk
Out of all of these, defaults
is the slowest because it involves spawning and executing a whole separate executable to read one value. defaults
is implemented via 2, which is implemented via 3 at the end. In order to speed this up, I just used option 4 as bat
's needs are fairly simple. Using CFPreferences
would have also worked but the use of #![deny(unsafe_code)]
indicated that would have been in conflict with the crate's goals since calling C APIs requires unsafe
by nature.
If bat
wanted to do this 100% as-intended by Apple, and possibly take advantage of any OS-level caching, CFPreferences.framework
would be the way. If you're good with the unsafe
required, happy to swap out the implementation. Though I don't ever really expect the file reading method to break.
So this new implementation reads the hardcoded settings path and directly parses the plist data with the plist
crate (already in the dependency tree from another crate, which was nice). As a result, in a release build, reading the theme is now 12x faster and pretty much imperceptible. The lowest time I saw with the old implementation was 4-5ms, while a release build call to macos_dark_mode_active
now takes <500us on an M1 Max MacBook.