dotnet / linker

387 stars 126 forks source link

Fix quadratic algorithm in CompilerGeneratedState #3150

Closed agocke closed 1 year ago

agocke commented 1 year ago

The way this code was supposed to work was that it would scan the compiler- generated type and all its descendents, record each generated type it found, then fill in information for all of the found types. The way it actually worked was that it would scan the descendents, record each generated type, then try to fill in information for all generated types found in the program. This is quadratic as you start adding types, as you rescan everything you've added before. The fix is to record just the types from the current pass, and then add them to the larger bag when everything's complete.

agocke commented 1 year ago

This isn't quite ready -- I have to create some test that will demonstrate the problem and verify the fix.

vitek-karas commented 1 year ago

Would be interesting to get some perf numbers to see how much this helps.

agocke commented 1 year ago

Turns out this change is less impactful than I thought. I created a test program with 10000 classes, each with one async method and one lambda -- generating ~20000 types. It looks like the ILLink time goes from 15s to 9.5s.

Overall, worth doing, but this will likely only make a significant difference for programs with lots and lots of generated types.

There's no way this could be a useful test case when running constantly -- I'll probably try to find some place to check it in and leave it disabled, so in case anyone wants to make any improvements here they can run the test and give it a try.