NetEscapades.EnumGenerators icon indicating copy to clipboard operation
NetEscapades.EnumGenerators copied to clipboard

Generated code can severely impact runtime of coverlet

Open davhdavh opened this issue 2 years ago • 4 comments

FYI https://github.com/coverlet-coverage/coverlet/issues/1573

Something about this way of making TryParse, makes coverlet extremely slow:

        public static bool TryParse(
#if NETCOREAPP3_0_OR_GREATER
            [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
#endif
            string? name, 
            out global::TestProject1.MyEnum value, 
            bool ignoreCase, 
            bool allowMatchingMetadataAttribute)
        {
            if (ignoreCase)
            {
                switch (name)
                {
                    case string s when s.Equals(nameof(global::TestProject1.MyEnum.Test000), global::System.StringComparison.OrdinalIgnoreCase):
                        value = global::TestProject1.MyEnum.Test000;
                        return true;

davhdavh avatar Dec 28 '23 04:12 davhdavh

Errr... wat 😅 Thanks for the heads up, I assume this is a coverlet issue though... 😄

andrewlock avatar Jan 02 '24 21:01 andrewlock

Yeah, but might consider changing the generated code a bit.

public static bool TryParse(...) {
 if (constant)
  lotsOfCode1
 else
  lotsOfCode2
}

will cause the JIT compiler to not be able to inline the constant evaluation because the function is just too big.

A better approach is:

public static bool TryParseIgnoreCase(...) {lotsOfCode1}
public static bool TryParseWithCase(...) {lotsOfCode2}
public static bool TryParse(...) {
 if (constant)
  return TryParseIgnoreCase(...);
 else
  return TryParseWithCase(...);
}

The Jit can then replace the call to TryParse to the proper method if ignoreCase is a constant.

davhdavh avatar Jan 04 '24 02:01 davhdavh

Is that really going to make that much difference? Sure it halves the lines inside the method, but if there's 3500 lines of code and sequence points, is it going to make a decisive difference? I mean, we totally could do it, but is it going to solve anything?

andrewlock avatar Feb 15 '24 20:02 andrewlock

Assuming the algorithm they use scale as O(n^2), halfing the number of code points would be same as cutting runtime to the squareroot. That's pretty significant.

davhdavh avatar Feb 16 '24 04:02 davhdavh

Finally got around to making a PR to split the TryParse method as you suggested - hopefully that fixes the issue!

andrewlock avatar May 14 '24 21:05 andrewlock