When compiling a very large C++ unit test that does a great deal of logging, the following pattern emerged: roughly 15% of the compilation time (26 seconds) was spent adding builtin operator overloads. This resulted in a large amount of effort, usually including a check for IsStandardConversion trying to convert the arguments to the parameter types. When I counted the number of standard conversions, there were 2.9 million in this TU. Tracing back, well over a million stemmed from a single phenomenon: builtin operator overloads for the permutation of arithmetic types (36 total) even though none of the argument types were or could convert to arithmetic types.<div>
<br></div><div>The single worst offender, by a huge margin, is basic_ios<> derived stream objects (all standard streams) and the operator<< overload.</div><div><br></div><div>John McCall suggested pruning builtin operator overloads when there is no non-record type being considered. This helps, but not tremendously. On my test case it took my rough approximation of the number from 2.9 million to 2.7 million. The reason is that basic_ios<> in C++98 and '03 has a conversion operator to void*. Thus I went further and also tracked whether any of the candidate types involved in all of the arguments were either arithmetic or enumeral types. If none are, we skip adding the arithmetic operator overloads altogether. This dropped the number of conversions we attempt from 2.7 million to around 1.5 million. Total parse time for the test case file drops by over 10% (new time of 23 seconds).</div>
<div><br></div><div>The code is pretty gross. I'd like to do some further cleanups, specifically factoring the logic for each operation type out into a function so that the switch will just select the function to call, and the gotos and fall-through currently employed can be represented as calls. Also, the class maintaining state for the candidate types could use some cleaning. Let me know if I should clean before or after adding the new functionality. Clearly, the patch is relative to the current code.</div>