-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SqlClientEventSource.Log.TraceEvent(...) leads to not necessary allocations in several places #681
Comments
@TrayanZapryanov Thanks for bringing this up to our attention. The memory allocation goes to variable
will be moved inside an if statement. I will look up for the rest, |
I've continued my experiment and benchmarked also against "System.Data.SqlClient" nuget(4.8.1). Benchmark: [MemoryDiagnoser]
and results:
|
Running Create and Create_System under a memory profile it looks to me as If the difference is down to stringbuilder tostring calls in |
I've also wonder as we have cache by connection string for connections, is it worth to use similar cache for parsed key/value pairs? This should be ultimate solution, as normal case is to use two or three connection strings per application. And we can save whole parsing... |
Caching is tricky and likely to hit locking issues, the parameter names are all constants but unless we can demonstrate clear benefits to keeping a cache and a good eviction policy I doubt we'll be able to do much good with it. |
Maybe a simple LRU cache with ten entries can handle 90% of standard usages in one app. Of course reducing allocations will help too, but should not be the main focus. ConnectionPool key can be used as identifier. |
Sure but the LRU has to be shared which will require locking and when you're moving fast those locks add up. The alternative is to use lock free structures which either require careful implementation and auditing or use of platform provided versions (does the library already reference immutable? if so that's a freebie) Give it a try I suppose and see if you can get any benefit. |
There are several places where calls to SqlClientEventSource.Log.TraceEvent() are allocating no matter that EventSource is not enabled.
string cstr = ((null != connectionOptions) ? connectionOptions.UsersConnectionStringForTrace() : ""); SqlClientEventSource.Log.TraceEvent("<prov.DbConnectionHelper.ConnectionString_Set|API> {0}, '{1}'", ObjectID, cstr);
A simple benchmark for creating an SqlConnection :
`
[MemoryDiagnoser]
public class Benchmarks
{
[Benchmark]
public SqlConnection Create()
{
return new SqlConnection("Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;");
}
}`
produces following results:
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.388 (2004/?/20H1)
Intel Core i7-4770 CPU 3.40GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.302
[Host] : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
DefaultJob : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
Before:
After:
The text was updated successfully, but these errors were encountered: