-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Suppress logging checks in query when not required, caching for 1 second #24304
Conversation
Note: just avoiding Guid.NewGuid (command correlation ID) yielded a ~3% RPS improvement (BDN measures this method, which does native interop, at 800ns). |
FWIW |
Wauw - what RPS rate is Dapper at? |
Thanks @adamsitnik, good to get confirmation on Guid.NewGuid... @ErikEJ Dapper is at 93453, you can follow progress at: #23611 (comment) |
@roji Doses this mean that if I have logging set for a single event that only happens occasionally when a certain error occurs, then I will have very little chance of seeing that event in the log because it will likely happen sometime within the 1 second cache window? |
Errors are exempt from this - they're always logged (there's also no perf overhead for that). Basically, for high-perf non-error events only, if we try to log and discover nothing was set up (diagnostics listener, logger, interceptor..), we abstain from logging again for one second. This means we support changing of logging config at runtime (e.g. adding a diagnostics listener), but users may have to wait for up to 1 second for that to take effect. |
@@ -549,7 +578,7 @@ public virtual RelationalDataReader ExecuteReader(RelationalCommandParameterObje | |||
connection.ConnectionId, | |||
exception, | |||
startTime, | |||
_stopwatch.Elapsed, | |||
DateTimeOffset.UtcNow - startTime, |
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.
@ajcvickers was there a specific reason to use StopWatch instead of just subtracting timestamps, given that we already took the starting timestamp? Was this a concern with increased timer precision or something?
@roji I would very much like to hear what the rest of the team think about this. :-) @dotnet/efteam |
@ajcvickers that looks like a very euphemistic comment to me 🔥🔥🔥 But yeah, let's discuss. We can always fall back to some sort of global flag opt-out or something. |
@roji I'm trying hard not to state my opinions strongly before others get a chance to speak. :-) |
b94f544
to
a666e4b
Compare
This certainly ended up being more work than expected... @AndriySvyryd @ajcvickers This bumps our TechEmpower Fotunes RPS from 82,892 to 91,266, roughly 10%. |
Hello @roji! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
Apologies, while this PR appears ready to be merged, I've been configured to only merge when all checks have explicitly passed. The following integrations have not reported any progress on their checks and are blocking auto-merge:
These integrations are possibly never going to report a check, and unblocking auto-merge likely requires a human being to update my configuration to exempt these integrations from requiring a passing check. Give feedback on thisFrom the bot dev teamWe've tried to tune the bot such that it posts a comment like this only when auto-merge is blocked for exceptional, non-intuitive reasons. When the bot's auto-merge capability is properly configured, auto-merge should operate as you would intuitively expect and you should not see any spurious comments. Please reach out to us at fabricbotservices@microsoft.com to provide feedback if you believe you're seeing this comment appear spuriously. Please note that we usually are unable to update your bot configuration on your team's behalf, but we're happy to help you identify your bot admin. |
It seems a bit of an odd choice to me, that the non-deterministic behavior is the default for a logging/event infrastructure. Doesn't this introduce a whole new level of complexity/uncertainty, because it can give you back inaccurate/wrong results now at will? With the current implementation, does calling |
@lauxjpn we discussed this at length internally. The only non-determinism here is when your logging/DiagnosticListener/interception configuration changes as the program is already running. However, in the general case there's already a race condition between the code (or user) changing the configuration and the running program; for example, there already isn't any guarantee exactly when a new DiagnosticListener starts getting events as you're registering it. Since in general, we assume that runtime changes to logging/DiagnosticListener/interception are rare, it seemed more useful to users to have EF run faster by default, and to provide an opt-out if needed.
Yes. |
Yeah, so it is considered too obscure then. It is possible to do this deterministically without race condition (which can be somewhere between simple and hard, depending on the app), but I guess its fair that the scenario is not a very common one. Just thought it was weird, since making this opt-in would definitely not break anyone's code and not matter to 99% of users in regards to performance anyhow, for which the very high throughput scenario is just not a concern. The few users that care about this level of performance, would likely do some research and actually read the appropriate docs about it, and thereby learn about the switch to opt-in. Anyway, it seems that the decision has already been made. BTW, I like the general EF Core concept of letting users control the impact of expensive features. Makes it much more competitive with micro ORMs despite being feature rich. |
If no logging occurs (no interceptor, MS.Extensions.Logging, DiagnosticSource...), cache this fact and skip logging entirely for 1 second. This allows DiagnosticListeners and MS.Extensions.Logging to be modified at runtime without paying the price of checking at every single query execution.
This brings our Fortunes RPS up from 82167 to 91208, an 11% increase.
An alternative approach is a global flag to disable (perf-sensitive?) logging. I experimented with commenting out logging in these paths, and the difference seem very small; small enough IMHO to prefer this, which benefits all users without a special opt-in.
This PR is just a prototype - if the approach is OK I'll complete it. This is based on #24207, look at the last commit only.