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

WithWarnings uses EnsoHashMap to speed things up #10555

Merged
merged 80 commits into from
Aug 7, 2024

Conversation

Akirathan
Copy link
Member

@Akirathan Akirathan commented Jul 15, 2024

Closes #8682

Pull Request Description

Majority of warnings handling is now done via newly introduced nodes. Moreover, the underlying representation of warnings storage in WithWarnings was changed from Warning[] to EnsoHashMap.

Important Notes

  • Remove ArrayRope.

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • Ensure no regressions in engine and stdlib benchmarks

@Akirathan Akirathan added CI: No changelog needed Do not require a changelog entry for this PR. CI: Clean build required CI runners will be cleaned before and after this PR is built. labels Jul 15, 2024
@Akirathan Akirathan self-assigned this Jul 15, 2024
Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

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

Pavel, you wrote:

the performance is much worse so far, will investigate closely tomorrow

I think the approach you are using is correct. I cannot say why it is slow.

I'd like to advocate usage of specialized Node classes to manipulate WithWarnings. Ideally WithWarnings is an opaque class without any methods that can only be manipulated by associated nodes.

out.println(" @Override");
out.println(" public Object call(VirtualFrame frame, Object[] args) {");
out.println(" return handleExecute(frame, extra, body, args);");
out.println(" return handleExecute(frame, extra, body, insertNode, interop, args);");
Copy link
Member

Choose a reason for hiding this comment

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

Interesting. I can't say I like this at all! I don't want new arguments to handleExecute, if possible... can we keep handleExecute untouched and just wrap all calls to handleExecute with proper warnings handling magic?

Copy link
Member Author

Choose a reason for hiding this comment

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

That sounds very difficult. handleExecutes strips warnings from almost all the arguments, and then reassembles these warnings into the result. Doing this outside of handleExecute would mean that we would need to process arguments also outside handleExecute.

Why don't you like additional arguments to handleExecute?

out.println(
" if ("
+ arrayRead(argumentsArray, arg.getPosition())
+ " instanceof WithWarnings) {");
+ " instanceof WithWarnings withWarnings) {");
Copy link
Member

Choose a reason for hiding this comment

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

Recently I was claiming to @GregoryTravis that instanceof WithWarnings isn't the right way to check for warnings. Is or isn't it the right way in this case? Is or isn't it the right way in Greg's case?

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case, checking via warnsLibrary.hasWarnings(x) is not possible. The reason is that later, we fetch the value out of withWarnings via withWarnings.getValue(), which retains the old warnings. If you checked for warnings with warnsLibrary.hasWarnings(x), you would need to fetch the value via warnsLibrary.removeWarnings(x), and that does not retain old warnings. I have already tried to implement it that way, but some tests in Warning_Spec on Warning.get_all wrap_errors=True were failing.

Copy link
Member Author

Choose a reason for hiding this comment

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

Is or isn't it the right way in Greg's case?

Generally, I would prefer the check to be done via WarningsLibrary. This case in MethodProcessor is a bit special, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

On my branch, without these changes, the WarningsLibrary approach looks good:

#10725 (comment)

Should I wait for this to be merged and benchmark my changes before merging them?

Copy link
Member Author

Choose a reason for hiding this comment

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

@GregoryTravis I have just scheduled benchmarks for this PR. All other tests are already successful. If benchmarks are OK, I will merge it. Wait, please before I compare the benchmarks, I will ping you then.

@Akirathan
Copy link
Member Author

Akirathan commented Aug 6, 2024

GitHub
Hybrid visual and textual functional programming. Contribute to enso-org/enso development by creating an account on GitHub.
GitHub
Hybrid visual and textual functional programming. Contribute to enso-org/enso development by creating an account on GitHub.

Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

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

This is a huge change and it'd be better to get it finally in. These are the benchmarks results I see:

sbt:runtime-benchmarks> benchOnly Warning
[info] Benchmark                                          Mode  Cnt   Score   Error  Units
[info] WarningBenchmarks.diffWarningRandomElementsVecSum  avgt    3  12.885 ± 3.815  ms/op
[info] WarningBenchmarks.noWarningsVecSum                 avgt    3   0.006 ± 0.001  ms/op
[info] WarningBenchmarks.randomElementsVecSum             avgt    3   0.034 ± 0.014  ms/op
[info] WarningBenchmarks.sameWarningVecSum                avgt    3   1.842 ± 0.306  ms/op

It is far from ideal, but if we are faster than current develop and CI is green, let's integrate and continue this endeavor in another PR.

@Akirathan
Copy link
Member Author

Comparing the benchmark results with develop:

  • In engine benchmarks, I can see that all WarningBenchmarks results are better than on develop. More specifically:
    • WarningBenchmarks.diffWarningRandomElementsVecSum: 137 vs 27
    • WarningBenchmarks.noWarningsVecSum: 0.16 vs 0.0031
    • WarningBenchmarks.randomElementsVecSum: 0.206 vs 0.022
    • WarningBenchmarks.sameWarningVecSum: 8.311 vs 1.757
  • stdlib benchmarks are without any regressions.

Conclussion: Benchmarks look very good.

@Akirathan Akirathan added the CI: Ready to merge This PR is eligible for automatic merge label Aug 7, 2024
@mergify mergify bot merged commit c2c6712 into develop Aug 7, 2024
41 of 42 checks passed
@mergify mergify bot deleted the wip/akirathan/8682-with-warnings-hashmap branch August 7, 2024 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Clean build required CI runners will be cleaned before and after this PR is built. CI: No changelog needed Do not require a changelog entry for this PR. CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Migrate WithWarnings to use EnsoHashMap to speed them up significantly
3 participants