Skip to content
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

perf: do not compute log message until required #5410

Merged
merged 6 commits into from Nov 16, 2023
Merged

Conversation

TimBeyer
Copy link
Contributor

@TimBeyer TimBeyer commented Nov 14, 2023

What this PR does / why we need it:
Before letting go of the whole performance epic, I did one last round of CPU profiling and noticed that for large projects we spend a large amount of time calling functions that are only used in higher log levels, which aren't actually really set most of the time. The problem is that we do the heavy processing for the log entries, but then we eventually discard them.
Thus I changed the logger so it can accept a callback, and if nothing logs it, the callback never gets called.

I don't want to spend large amounts of time on this anymore, and this was just a quick search and replace thing, so if it works let's consider merging it, if not, we can still keep this around as inspiration.

For now this was only applied to the silly log level since that's where the most expensive log lines were coming from.

This improves performance of garden validate on a project with 500 modules from ~32 to ~25 seconds.
So this change gives an about 20% time saving for very large projects, which is pretty nice for such a simple change.

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

…eeded

The idea is that sometimes we do heavy operations for silly logs, but we then discard just the log output.
Instead, we can pass a callback and if the log is never needed for display, it won't actually call the heavy operations.
There might be multiple loggers resolving the message eventually.
Wrap it in `memoize` so that it only gets resolved once.
@TimBeyer TimBeyer changed the title perf: deferred logging perf: do not compute log message until required Nov 15, 2023
@@ -318,38 +340,38 @@ export abstract class Log<C extends BaseContext = LogContext> implements LogConf
/**
* Render a log entry at the silly level. This is the highest verbosity.
*/
silly(params: string | LogParams) {
silly(params: Msg | LogParams) {
Copy link
Member

@stefreak stefreak Nov 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might want to enforce using the closure instead of a string for silly

Copy link
Member

@stefreak stefreak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love this! It really is a very simple change for a 20% performance improvement

@TimBeyer TimBeyer added this pull request to the merge queue Nov 16, 2023
@@ -406,28 +406,28 @@ export class GraphSolver extends TypedEventEmitter<SolverEvents> {

if (status?.aborted || status?.error) {
// Status is either aborted or failed
this.log.silly(`Request ${request.getKey()} status: ${resultToString(status)}`)
this.log.silly(() => `Request ${request.getKey()} status: ${resultToString(status)}`)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For for the record, these resultToString calls were the main culprits of the time spent in logging by using CircularJSON.stringify.

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 16, 2023
@stefreak stefreak added this pull request to the merge queue Nov 16, 2023
Merged via the queue into main with commit 14e713b Nov 16, 2023
45 checks passed
@stefreak stefreak deleted the perf/deferred-logging branch November 16, 2023 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants