Hi Andreas,
Some background: tup was designed with the file monitor in mind, with the idea that the build system should already know which files the user changed ahead of time, and then the dependency information can be structured in a way to take advantage of that information. I was expecting that 'make' spends too much time calling stat() on a bunch of unnecessary files, and that this would be the bulk of the time savings. But in reality, make also spends a lot of time parsing the Makefiles and processing all the funky variable constructions that people end up with (like a bunch of $(call) and $(eval) and such). Tup separates out the parsing into a separate phase, and so most of the time that can all be skipped. The partial DAG that tup constructs is also much smaller than a full DAG that a make-like system would use, so it needs to do less work overall there.
In practice, I almost never use the file monitor. Without the file monitor, tup defaults to "scanning mode", where it simply walks the whole tree from the top of the tup hierarchy (ie: where 'tup init' was run, and the .tup directory exists). So you can determine how much exactly the monitor would save you by running 'time tup scan'. On Linux at least, even for a reasonably large project (72k files, roughly 5k commands), the scan takes 260ms on my machine, which is noticeable but still low enough that I don't bother running the monitor on it most of the time.
Of course, Windows is pretty notorious for having much worse file I/O than Linux. You can get an idea for the scanning overhead very easily (without writing any Tupfiles) by going to the top of your project directory and doing something like:
$ tup init
$ tup
# Run this once to initialize the database
$ tup
[ tup ] [0.000s] Scanning filesystem...
[ tup ] [0.261s] Reading in new environment variables...
...
The time on the second line (0.261s in this case) is the time it took to scan, which is all the time the monitor would save.
Note that in comparison to something like make or ninja, it is very easy to construct a case where the scanning mode of tup performs very poorly. Make or Ninja will only look at the files that you declare in the Makefile/ninja files, while tup will scan the whole tree, even if you don't have any Tupfiles at all. Tup could certainly be improved in this case but only tracking files that are mentioned in the Tupfiles and/or are detected as dependencies, but again that would only help when scanning, and the upper bound of the benefit is the time it takes scan to run. In my experience (again, on Linux), the time tup saves by using its more intelligent partial-DAG construction more than makes up for the time for the naive scanning algorithm. Not to mention the peace-of-mind of having automated dependency checking!
I'm curious what your results are and if you find the scanning time prohibitive for your project.
-Mike