Skip to content

Regression in .net 9 and .net 10 #126237

@WindingWinter

Description

@WindingWinter

Main Description

I can confirm that there is a regression when it comes to

Math.Sqrt(x*x+y*y)

method.

I have a nunit test test case to reproduce it. It fits nicely into a single project with "only" some 16 main classes and a single test method.

Running the EXACTLY same code in .net 8.0, .net 9.0 and .net 10.0 will yield different results

.Net 8.0

 Overlap_BenchmarkIterations
   Source: BenchmarkTest.cs line 958
   Duration: 1.2 sec
 Standard Output: 
   Runtime: .NET 8.0.25
   1000 iterations: 1210ms
   Per call: 1210.47µs

.Net 9.0

 Overlap_BenchmarkIterations
   Source: BenchmarkTest.cs line 958
   Duration: 3.9 sec
 Standard Output: 
   Runtime: .NET 9.0.14
   1000 iterations: 3811ms
   Per call: 3811.10µs

.Net 10.0

Overlap_BenchmarkIterations
   Source: BenchmarkTest.cs line 958
   Duration: 3.4 sec
  Standard Output: 
    Runtime: .NET 10.0.5
    1000 iterations: 3371ms
    Per call: 3371.88µs

See, the time taken for .net 9.0 is about 3 times as much as .net 8.0! even though that they run on exactly the same code.

The main regression happens from .net 8.0 to .net 9.0 version. .Net 10 does register some improvements from .Net 9.0 (on unrelated matters), but that's not nearly enough to cover the lost ground.

Additional observation

In the method XMath.Distance2D

    public static double Distance2D(PointD pt1, PointD pt2)
    {
        double deltax = pt2.X - pt1.X,
            deltay = pt2.Y - pt1.Y;
#if NET8_0_OR_GREATER
        return Math.Sqrt(deltax * deltax + deltay * deltay);
        //return double.Hypot(deltax, deltay);   // this will give some improvement
#else
        return Math.Sqrt(deltax * deltax + deltay * deltay);
#endif
    }

You can use double.Hypot(deltax, deltay) in .net 9.0 and .net 10.0, and you will find that hypot is actually faster than sqrt in the same .net version ( though of course still slower than sqrt in .net 8.0 version), which really shouldn't be the case, as hypot is more robust and contains more checking.

And additional source of confirmation comes from using VS 2026 performance profiler to profile the code, and for the above method, I can confirm that in .net 10.0, the dotnet runtimes spends far more time ( roughly 10x) in Math.Sqrt than in the above two deltax and deltay statements, but in .net 8.0, they spend about equal time in three statements each.

Computer Information

Processor	12th Gen Intel(R) Core(TM) i7-12650H (2.70 GHz)
NumberOfCores 10
NumberOfLogicalProcessors 16
Installed RAM	32.0 GB (31.7 GB usable)
System type	64-bit operating system, x64-based processor
Pen and touch	No pen or touch input is available for this display
Edition	Windows 11 Home Single Language
Version	25H2
Installed on	‎1/‎24/‎2026
OS build	26200.7623
Experience	Windows Feature Experience Pack 1000.26100.275.0

Urgency

This is critical as we are developing computationally heavy software, and upgrading to .net 10 seems like a must, and it is causing deep performance regression on our software. Our internal unit tests show that in general the overall application performance can degrade by as much as 30%.

Workaround

NONE discovered so far. Trying to trick the compiler into doing proper optimization by using Math.Pow(x,2) and so on, failed. So any workaround will be welcomed.

Project

SqrtRegression.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions