facebook / watchman

Watches files and records, or triggers actions, when they change.
https://facebook.github.io/watchman/
MIT License
12.57k stars 987 forks source link

CMake option to enable statically linking some of the libraries used #1023

Open chandlerc opened 2 years ago

chandlerc commented 2 years ago

Hello,

On macOS it seems like some of the libraries used by Watchman result in the binary being very slow to start. On my x86 MBP with the Homebrew installed binary:

Benchmark 1: watchman --version
  Time (mean ± σ):     108.4 ms ±   6.4 ms    [User: 83.1 ms, System: 7.9 ms]
  Range (min … max):    98.7 ms … 123.5 ms    20 runs

I can reproduce this by building myself, so I don't think it has anything to do with Homebrew.

I profiled it, and it looks like its spending most of its time loading shared libraries -- likely hitting lots of page faults and having to do a lot of complex symbol resolution due to the large number and complex structure of C++ template symbols. Folly, and Thrift libraries have many thousands of symbols exported. =[

Honestly, even 100ms is pretty fast and for most applications would be completely fine. However, because a common use case for running the watchman command is to optimize the latency of commands like git status w/o touching the filesystem, it seems really unfortunate for the binary to require ... well ... touching the filesystem a lot. And with the current overhead, 2 invocations adds up to a quarter second of latency pretty quickly. Fundamentally, the watchman binary is often used in an extremely latency sensitive setting per-execution, and likely needs some unusual steps to make that work well on non-Linux platforms.

It would be great to have a CMake option to link a bunch of the heavy-weight C++ libraries statically into the binary so that its startup could be a bit lower latency. I tried a few experiments to achieve this and wasn't successful sadly.

chandlerc commented 2 years ago

Running env DYLD_PRINT_BINDINGS=1 watchman --version is a good way to see just how much work Folly and Thrift in particular are causing here because of the huge number and size of C++ templates and such.

chadaustin commented 2 years ago

I told you I'd respond Monday, but then I got sick! Looking now. The macOS binaries we ship via GitHub Actions are statically-linked to folly and thrift. The Homebrew builds are community-maintained. It looks like the homebrew build doesn't explicitly request shared libraries, so I wonder what's going on. The only macOS machine I have is my work laptop, and we avoid Homebrew, so it's hard to test manually.