-
Notifications
You must be signed in to change notification settings - Fork 317
Perf | Reuse XmlWriterSettings, eliminate MemoryCacheEntryOptions allocations #3791
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
base: main
Are you sure you want to change the base?
Conversation
Lazily initialize these where the class might be used without needing to support XML.
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
| AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(ThreadRetryCacheTimeoutInMinutes) | ||
| }; | ||
| ThreadRetryCache.Set<string>(Thread.CurrentThread.ManagedThreadId.ToString(), retryThreadID, options); | ||
| ThreadRetryCache.Set<string>(Thread.CurrentThread.ManagedThreadId.ToString(), retryThreadID, absoluteExpirationRelativeToNow: TimeSpan.FromMinutes(10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue to use constant for timeout
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks - I've reintroduced the various constants in this comment and elsewhere.
| // Cache timeout of 8 hours to be consistent with jwt validity. | ||
| private static int enclaveCacheTimeOutInHours = 8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Continue using constant (convert it to const instead)
| AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(10) | ||
| }; | ||
| _cache.Set<bool>(cacheLookupKey, result, options); | ||
| _cache.Set<bool>(cacheLookupKey, result, absoluteExpirationRelativeToNow: TimeSpan.FromDays(10)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce const for magic number
| AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(10) | ||
| }; | ||
| _cache.Set<Dictionary<string, SqlCipherMetadata>>(cacheLookupKey, cipherMetadataDictionary, options); | ||
| TimeSpan expirationPeriod = TimeSpan.FromHours(10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce const for magic number
| AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1) | ||
| }; | ||
| rootSigningCertificateCache.Set<X509Certificate2Collection>(attestationUrl, certificateCollection, options); | ||
| rootSigningCertificateCache.Set<X509Certificate2Collection>(attestationUrl, certificateCollection, absoluteExpirationRelativeToNow: TimeSpan.FromDays(1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce const for magic number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR implements two memory optimization improvements: (1) reuses XmlWriterSettings objects via static fields instead of allocating them repeatedly, and (2) eliminates allocations of MemoryCacheEntryOptions objects by using the MemoryCache.Set overload that accepts expiration timespan directly.
- Caches
XmlWriterSettingsobjects in static fields with lazy initialization inTdsParser,ValueUtilsSmi, andSqlStreamingXml - Refactors all
MemoryCache.Setcalls to useabsoluteExpirationRelativeToNowparameter directly instead of creatingMemoryCacheEntryOptionsobjects - Improves code clarity by moving cache timeout comments closer to their usage points
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| VirtualSecureModeEnclaveProviderBase.cs | Eliminates MemoryCacheEntryOptions allocation by using direct parameter |
| TdsParser.cs | Adds static fields for async/sync XmlWriterSettings with lazy initialization |
| SqlSymmetricKeyCache.cs | Eliminates MemoryCacheEntryOptions allocation by using direct parameter |
| SqlStream.cs | Adds static readonly XmlWriterSettings field in SqlStreamingXml class |
| SqlQueryMetadataCache.cs | Eliminates MemoryCacheEntryOptions allocations and extracts expiration period to local variable for reuse |
| SignatureVerificationCache.cs | Eliminates MemoryCacheEntryOptions allocation by using direct parameter |
| ValueUtilsSmi.cs | Adds static field for XmlWriterSettings with lazy initialization |
| EnclaveSessionCache.cs | Eliminates MemoryCacheEntryOptions allocation and moves timeout comment inline |
| EnclaveProviderBase.cs | Eliminates MemoryCacheEntryOptions allocation and inlines constant value |
| AzureAttestationBasedEnclaveProvider.cs | Eliminates MemoryCacheEntryOptions allocation by using direct parameter |
Comments suppressed due to low confidence (2)
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs:12775
- Write to static field from instance method, property, or constructor.
? (s_asyncWriterSettings ??= new() { CloseOutput = false, ConformanceLevel = ConformanceLevel.Fragment, Async = true })
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs:12776
- Write to static field from instance method, property, or constructor.
: (s_syncWriterSettings ??= new() { CloseOutput = false, ConformanceLevel = ConformanceLevel.Fragment });
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Introduce and reintroduce constants containing cache expiration periods
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/EnclaveSessionCache.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/Server/ValueUtilsSmi.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParser.cs
Outdated
Show resolved
Hide resolved
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
Turn the lazy field initialisation into a property, and the TimeOutInX constants which were only used to create a TimeSpan into a static readonly TimeSpan.
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
paulmedynski
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
Description
This is a minor set of improvements in memory usage which I noticed while looking at the XML access pathway and thinking about some of the layers of caching within SqlClient.
The first commit caches and reuses
XmlWriterSettingsobjects. As per the remarks in the documentation, these can be reused and so don't need to be allocated every time. I've promoted these to astatic readonlyfield in theSqlStreamingXmlclass because this is only used when reading XML data. The other places this is used areTdsParserandValueUtilsSmi, and these don't necessarily need to use XML functionality so I lazily allocate them on first use.In the second commit, we eliminate allocations of
MemoryCacheEntryOptionsobjects. These are essentially DTOs which are used to modify the expiration times of entries in various MemoryCaches. Rather than allocating a new object, we can use a different overload which accepts the expiration timespan directly.Issues
None.
Testing
Local tests of these pathways pass - could someone run CI please?