-
-
Notifications
You must be signed in to change notification settings - Fork 70
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
feat: Rule Performance Statistics #108
Conversation
|
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 for putting this together. I've left a few comments on the approach.
Something I'd love is more granular performance data per rule - I.e. Breakdown time spent in Currently the timing only displays the sum total of time spent in Right now the time spent spent in esquery is not tracked - which means that rules can appear faster by moving logic to a selector - which can fool users into thinking a rule is faster than it is. Time spent in a rule's There's also pre-processor performance and parser performance that isn't tracked - which would be good to see in more complex project setups. |
After sleeping on it, I also believe that a better path forward is to create a generic way to report timing information in the report that is sent to formatters. So, rather than keying in on rule performance, I could see a generic data structure like this being added in the result object:
And maybe we have a We could always start with rule timing and add the others later (after the rewrite, we should have more granular data to use than we do right now). |
Ok, so instead of providing a specialized formatter, any formatter could pick up this statistics object only when the
Sounds good! 👍🏼 As this is my first time going through this process: Do I now adapt the RFC text before implementing the changes in the POC or should the text and code be changed simultaneously as we progress? |
Actually, maybe
This is up to you. We don't require a POC to accept an RFC, we just want a detailed description of what an implementation might look like. So, we still want the details about which files will be modified and where, but you don't actually need to build it unless you want to. In some cases it can help to build a POC if you're not entirely sure, I myself tend to do small POCs of the more difficult parts of my RFCs just to validate I know what I'm doing. |
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.
@mnkiefer it looks like you agreed with the proposals I made, but the RFC hasn't been updated. Do you still plan on updating it?
@nzakas: Could we have another review on this? 😇 |
I just changed the visibility to public, you should now be able to navigate to the file. 👍 |
Just to clarify, when you say the linter isn't applying fixes, do you mean it's not writing to disk? Or that it's not producing |
It wasn't fixing the file, but I did have a combination of lint rules with some not auto-fixable, so that makes sense. 🙈 With your recent advice, I finally managed to come up with an example that has 2 fix passes: /*eslint no-regex-spaces: "error", wrap-regex: "error"*/
function a() {
return / foo/.test("bar");
} When I have some time this week, I will return to this, do some final testing, and report back as soon as I'm done. 👍 |
Awesome, thanks for the update. By default, ESLint does not output fixes to disk while linting. In order to output to disk, you'd need to call |
@nzakas: The above example produces the following
"stats": {
"directives": 0,
"fixPasses": 2,
"times": {
"passes": [
{
"parse": {
"total": 4.526709
},
"rules": {
"total": 1.266792,
"no-regex-spaces": {
"total": 1.063667
},
"wrap-regex": {
"total": 0.203125
}
},
"fix": {
"total": 0.001333
},
"total": 5.794834
},
{
"parse": {
"total": 0.770792
},
"rules": {
"total": 0.22520800000000002,
"no-regex-spaces": {
"total": 0.21666600000000003
},
"wrap-regex": {
"total": 0.008542000000000001
}
},
"fix": {
"total": 0.000334
},
"total": 0.9963339999999999
},
{
"parse": {
"total": 0.593667
},
"rules": {
"total": 0.031083,
"no-regex-spaces": {
"total": 0.013791999999999999
},
"wrap-regex": {
"total": 0.017291
}
},
"fix": {
"total": 0
},
"total": 0.6247499999999999
}
]
},
"violations": 0
} |
Unrelated: I think we can remove |
I agree! 👍 I have updated the RFC and POC accordingly and I think we have finally captured all of the requirements which have trickled in since we started. 🎉 What are the next steps and what needs to be done to move this into the final commenting phase? |
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.
LGTM. I think this is a good general direction to head in.
@mdjermanovic please review when you have a moment, and if there are no objections, we should move this to Final Commenting.
"fix": { | ||
"total": 0.001792 | ||
}, | ||
"total": 5.739875 |
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.
How do we calculate total
? From this example, it looks like total = parse + rules + fix. But, linter is also doing other things in each pass, e.g., processes inline configuration and adds globals, so the sum of only those parts of the process that we're individually tracking might be misleading.
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.
@mdjermanovic: Yes, the total is computed as you say. I agree that from this perspective, it might be confusing and be interpreted as the total lint timing.
@nzakas: Should we just leave it out (as we did in rules) or keep it and make it track the overall timing of a particular run?
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.
I'd keep it and make it track the overall timing of a particular pass (which should be >= parse + rules + fix).
@nzakas what do you think?
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.
Using it for the overall timing makes sense to me. 👍
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.
Ok, I've updated the implementation and RFC. Each pass total
time now corresponds to the time that is spent when running Linting code for ${debugTextDescription} (pass ${passNumber})
...
Please let me know if this aligns with what you had in mind. 👍
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.
The directives
and violations
fields aren't clearly defined.
Perhaps we could leave these fields for later, and for the first version of the stats feature focus on returning only timing data as @nzakas suggested in #108 (comment)?
@mdjermanovic: I'm fine with leaving them out for now. However, the suggested metrics by @bmish should definitely be included in future stats. @nzakas: Would you be ok with leaving them out or now? |
eslint/eslint#14597 proposes that ESLint directly prints out stats to the console, while this RFC proposes adding stats to |
I understand, I should have better phrased it as future outputs, it doesn't have to be in stats. I only wanted to make sure that information is not lost as the item was linked to this RFC and I was asked to include suppressions and violations here. This was just a heads up not to close that request. 🙏 |
Yup, I'm fine with leaving out |
Because we are just making tweaks at this point, I'm promoting this RFC to Final Commenting. |
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.
LGTM, thanks!
I left two small suggestions about the RFC text.
Also, I'm not sure if proof of concept supports the case when eslint is used with processors, but we can address that during the implementation.
Co-authored-by: Milos Djermanovic <[email protected]>
Co-authored-by: Milos Djermanovic <[email protected]>
The final commenting period is now closed. This RFC is accepted! 🎉 |
Summary
This document describes how to expose ESLint's
TIMING
information as well as collect additional runtime statistics to facilitate monitoring of rule/plugin development.Related Issues
eslint/eslint#16690