Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Core Singleton instance vs Transient instance performance

In ASP.NET Core Dependency Injection, I just wonder if registering Singleton instances will improve performance instead of registering Transient instances or not?

In my thinking, for Singleton instance, it just costs once time for creating new object and dependent objects. For Transient instance, this cost will be repeated for each service request. So Singleton seems to be better. But how much performance do we gain when using Singleton over Transient? Thank you in advance!

like image 327
tuq Avatar asked Feb 20 '19 15:02

tuq


People also ask

Should I use singleton or transient?

Use Transient lifetime for the lightweight service with little or no state. Scoped services service is the better option when you want to maintain state within a request. Singletons are created only once and not destroyed until the end of the Application. Any memory leaks in these services will build up over time.

What is singleton and transient in .NET Core?

Singleton is a single instance for the lifetime of the application domain. Scoped is a single instance for the duration of the scoped request, which means per HTTP request in ASP.NET. Transient is a single instance per code request.

Should repository be scoped or transient?

Accepted Answer. Simply put, your go-to lifetime should be "scoped". You should only use a singleton or transient lifetime if you have a good reason to do so.

Can singleton consume transient?

You should almost never consume scoped service or transient service from a singleton. You should also avoid consuming transient service from a scoped service.


3 Answers

Like others have said, performance should not make your decision here: performance will not be dramatically impacted either way. What should be your consideration is dependencies, both managed and unmanaged. Singletons are best when you're utilizing limited resources, like sockets and connections. If you end up having to create a new socket every time the service is injected (transient), then you'll quickly run out of sockets and then performance really will be impacted.

Transient scope is better when resource usage is temporary and of minimal impact. If you're only doing computation, for instance, that can be transient scoped because you're not exhausting anything by having multiple copies.

You also want to use singleton scope when state matters. If something needs to persist past one particular operation, then transient won't work, because you'll have no state, because it will essentially start over each time it's injected. For example, if you were trying to coordinate a concurrent queue, using semaphores for locks, then you'd definitely want a singleton scoped service. If state doesn't matter, then transient is probably the better scope.

Finally, you must look at other services your service has a dependency on. If you need access to scoped services (such as things that are request-scoped), then a singleton is a bad fit. While you can possibly use a service-locator pattern to access the scoped services, that's a faux pas, and not recommended. Basically, if your service uses anything but other singleton services, it should likely be scoped or transient instead.

Long and short, use a transient scope unless you have a good, explicit reason to make it a singleton. That would be reasons like mentioned above: maintaining state, utilizing limited resources efficiently, etc. If the service will work in a transient scope, and there's no good reason to do otherwise, use transient scope.

Now, ASP.NET Core's DI has both a "transient" and a "scoped" lifetime. Both of these are "transient" in the sense that they come and go, but "scoped" is instantiated once per "scope" (usually a request), whereas "transient" is always instantiated every time it is injected. Here, you should use "scoped" unless you have a good, explicit reason to use "transient".

like image 181
Chris Pratt Avatar answered Oct 09 '22 17:10

Chris Pratt


Like mentioned in the replies this isn't really a matter over performance.

For more details please see the link below where the difference is very elaborately explained. AddTransient, AddScoped and AddSingleton Services Differences

The only way that this will matter performance wise is if your constructor is doing a lot of stuff. This can and should be avoided though in all cases.

like image 1
swforlife Avatar answered Oct 09 '22 18:10

swforlife


I know that the performance here is not what you should looking for, but for a matter of curiosity, I made a sample benchmark app to evaluate the difference between AddSingleton and AddTransient, using BenchmarkDotNet

The solution that I used can be found here (Feel free to improve it): https://github.com/iheb719/BenchmarkDifferentServicesInstances

This was my summary :

My laptop specifications : BenchmarkDotNet=v0.13.1, OS=Windows 10.0.19042.1415 (20H2/October2020Update) Intel Core i7-9750H CPU 2.60GHz, 1 CPU, 12 logical and 6 physical cores .NET SDK=6.0.101 [Host] : .NET 6.0.1 (6.0.121.56705), X64 RyuJIT DefaultJob : .NET 6.0.1 (6.0.121.56705), X64 RyuJIT

My results :

Method Mean Error StdDev
CallSingletonApp 101.0 us 0.64 us 0.53 us
CallTransientApp 108.3 us 1.16 us 1.03 us

So there is really no significant difference between AddSingleton and AddTransient (of course, if you don't have huge treatments inside your constructors)

like image 2
ihebiheb Avatar answered Oct 09 '22 17:10

ihebiheb