Massive speedup to file_equal and file_to_string#1584
Conversation
There was a problem hiding this comment.
Pull request overview
This PR optimizes incremental generation performance by speeding up the “read existing file and compare” path used to skip redundant writes in cppwinrt.exe.
Changes:
- Replace
stringstream << rdbuf()file reads with a single bulk read sized up-front viatellg(). - Short-circuit
file_equalearlier by checking the on-disk file size before reading and comparing.
|
We can do what |
|
@jonwis, @lhecker There is probably more impactful possibilities for speeding up cppwinrt.exe. For example, we are spending nearly 10% of our processing time on repeated (~1M) |
I was testing some quality of life improvements, and I saw that in incremental situations when there are already headers in the output folder, cppwinrt.exe takes twice as long to run!
Before writing pending output, it reads the existing file in and compares it, skipping the write if the contents are identical. The comparison itself is fast enough, using
std::equalwhich boils down tomemcmp, but the read is usingstd::ifstream::operator<<to read astd::string, and this operation processes the file contents a single character at a time, resulting in tons of overhead.With this change, we now do a single bulk read of the file contents. Additionally, before we read the contents, we check the file size in the filesystem before reading the contents, allowing us to short-circuit even faster.
A before/after comparison on a Release x64 run of regenerating the local SDK projection without cleaning the output folder first, shows a 50% speedup in wall clock time.
Here's the results from an instrumented profile run in Visual Studio.


Before:
After:

