C
C#3w ago
Core

✅ Class instantiation takes too long

Hello, A class has many static properties, which are initialized in a static constructor so they’re set up when the first instance is created, and not when individual properties are accessed. The issue is that there's a method called TryParse which takes way too long, despite having all static properties initialized. The first call to it takes about 3-4 seconds. I put the TryParse method in the constructor, and here's the result:
c#
var a = new UaDetector.UaDetector();

sw.Stop();
Console.WriteLine($"{sw.ElapsedMilliseconds}ms");

sw.Restart();

var b = new UaDetector.UaDetector();

sw.Stop();
Console.WriteLine($"{sw.ElapsedMilliseconds}ms");
c#
var a = new UaDetector.UaDetector();

sw.Stop();
Console.WriteLine($"{sw.ElapsedMilliseconds}ms");

sw.Restart();

var b = new UaDetector.UaDetector();

sw.Stop();
Console.WriteLine($"{sw.ElapsedMilliseconds}ms");
1. instance: 5503ms
2. instance: 1ms
1. instance: 5503ms
2. instance: 1ms
I’m considering a hacky solution where I keep an internal counter and call TryParse only when the object is created for the first time. I have no idea what could cause this. Any feedback is appreciated. Below are all the classes involved in the object creation: 1. https://github.com/UaDetector/UaDetector/blob/main/src/UaDetector/UaDetector.cs 2. https://github.com/UaDetector/UaDetector/blob/main/src/UaDetector/Parsers/BotParser.cs 3. https://github.com/UaDetector/UaDetector/blob/main/src/UaDetector/Parsers/OsParser.cs 4. https://github.com/UaDetector/UaDetector/blob/main/src/UaDetector/Parsers/BrowserParser.cs 5. https://github.com/UaDetector/UaDetector/blob/main/src/UaDetector/Parsers/ClientParser.cs
12 Replies
mg
mg3w ago
could you clarify how the code/output relates to the issue the output doesn't match the code and i don't see any calls to TryParse from the sound of it, the first call to TryParse is causing the static constructor to be invoked, hence the long execution time
cned
cned3w ago
Have you profiled it? That’s far better than us trying to guess at what’s happening. This code is doing a lot, so the best way would be to run it under a profiler and see where the time is going.
Core
CoreOP3w ago
Is that done with Rider dotMemory? Sorry, the TryParse is slow, I gave that benchmark to justify my potential solution for it...
mg
mg3w ago
i don't think profiling is necessary at this point. it seems pretty likely that the long execution time is a result of the static constructor being invoked and compiling a couple dozen regex expressions
Core
CoreOP3w ago
But isn't the static constructor invoked, when the class is instantiated for the first time?
cned
cned3w ago
In rider, you can profile a unit test. So if you have a unit test (if not, another good skill to learn), you can click on the little green arrow for a test and choose “profile test”.
mg
mg3w ago
that's one scenario in which it's invoked that or before a static member is referenced
cned
cned3w ago
It will run and give you a little report of what happened.
mg
mg3w ago
which is consistent with the code/output you posted you construct the class, presumably for the first time, so the static constructor is invoked then, on the second instantiation, the execution time is fast also gonna jump the gun and bring up GeneratedRegex because i'm 90% sure that's what the solution is going to end up being
Core
CoreOP3w ago
this might be an issue, since the class itself is static, so to initialization of the properties will happen upon first access that's not possible, I'm targeting ns 2.0, net462 Thanks everyone, it seems like the problem is with static classes Should I call TryParse or access all static properties one by one in the instance constructor?
mg
mg3w ago
is the issue that the static constructor is taking too long?
Core
CoreOP3w ago
no, there is 1-2 class that are static. Engines will only initialize when it's first accessed, a static constructor will not solve the issue
c#
internal static class EngineParser
{
private static readonly IReadOnlyList<BrowserEngine> Engines;
...
}
c#
internal static class EngineParser
{
private static readonly IReadOnlyList<BrowserEngine> Engines;
...
}
But making the class non static and instantiating it will trigger the static constructor

Did you find this page helpful?