-
Notifications
You must be signed in to change notification settings - Fork 323
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
If cascades 5x slower than case-of due to limit of recursive inlining #5709
Comments
Pavel Marek reports a new STANDUP for today (2023-02-20): Progress: Created Enso benchmarks. Looking into the compilation logs from those benchmarks - there is too much clutter, compilation does not seem to get stable. Creating corresponding benchmarks in JMH. Finished other PR. It should be finished by 2023-02-22. |
Results from
We can see that the slowdown of nested if-expressions is increasing with the number of nested ifs. |
Pavel Marek reports a new STANDUP for today (2023-02-21): Progress: Created draft PR. Created a proper JMH benchmark. The performance comparison of |
Pavel Marek reports a new 🔴 DELAY for today (2023-02-24): Summary: There is 5 days delay in implementation of the If-then-else is 5x slower than equivalent case expression (#5709) task. Delay Cause: Returning back to this issue after some time. Did other important issues meanwhile. |
Pavel Marek reports a new STANDUP for today (2023-02-24): Progress: Compared compiler logs of if_bench vs case_bench and nothing suspicious found - only that code size of compilations from if_bench is slightly larger, but nothing suggesting that if_bench is 3x slower than case_bench. Sampler in VisualVM revealed nothing. Will continue with a brief look at IGV and fiddling with some profiles. It should be finished by 2023-02-27. |
During my work on #5845, I had some counterintuitive observations to this issue. 1.Adding diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
index 6770205a1..70a3fecc9 100644
--- a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
+++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
@@ -106,13 +106,13 @@ type Any
a == 147
== : Any -> Boolean
== self that =
- # If there is No_Such_Conversion, then `self` and `that` are probably
- # host or polyglot values, so we just compare them with the default comparator.
- eq_self = Panic.catch No_Such_Conversion (Comparable.from self) _-> Default_Comparator
- eq_that = Panic.catch No_Such_Conversion (Comparable.from that) _-> Default_Comparator
- case Meta.is_same_object eq_self Incomparable of
- True -> False
+ case Meta.is_same_object self that of
+ True -> True
False ->
+ # If there is No_Such_Conversion, then `self` and `that` are probably
+ # host or polyglot values, so we just compare them with the default comparator.
+ eq_self = Panic.catch No_Such_Conversion (Comparable.from self) _-> Default_Comparator
+ eq_that = Panic.catch No_Such_Conversion (Comparable.from that) _-> Default_Comparator
similar_type = Meta.is_same_object eq_self eq_that
case similar_type of
False -> False Even if I refactored 2.Extracting 3 nested case expressions to a different method (2x faster than 1): diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
index 70a3fecc9..ce4939d7a 100644
--- a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
+++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
@@ -108,21 +108,24 @@ type Any
== self that =
case Meta.is_same_object self that of
True -> True
- False ->
- # If there is No_Such_Conversion, then `self` and `that` are probably
- # host or polyglot values, so we just compare them with the default comparator.
- eq_self = Panic.catch No_Such_Conversion (Comparable.from self) _-> Default_Comparator
- eq_that = Panic.catch No_Such_Conversion (Comparable.from that) _-> Default_Comparator
- similar_type = Meta.is_same_object eq_self eq_that
- case similar_type of
- False -> False
- True ->
- case Meta.is_same_object eq_self Default_Comparator of
- True -> Comparable.equals_builtin self that
- False ->
- case eq_self.compare self that of
- Ordering.Equal -> True
- _ -> False
+ False -> self.my_eq that
+
+ my_eq self that =
+ # If there is No_Such_Conversion, then `self` and `that` are probably
+ # host or polyglot values, so we just compare them with the default comparator.
+ eq_self = Panic.catch No_Such_Conversion (Comparable.from self) _-> Default_Comparator
+ eq_that = Panic.catch No_Such_Conversion (Comparable.from that) _-> Default_Comparator
+ similar_type = Meta.is_same_object eq_self eq_that
+ case similar_type of
+ False -> False
+ True ->
+ case Meta.is_same_object eq_self Default_Comparator of
+ True -> Comparable.equals_builtin self that
+ False ->
+ case eq_self.compare self that of
+ Ordering.Equal -> True
+ _ -> False
3.Refactor the first diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
index 70a3fecc9..8edff6691 100644
--- a/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
+++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Any.enso
@@ -106,23 +106,21 @@ type Any
a == 147
== : Any -> Boolean
== self that =
- case Meta.is_same_object self that of
- True -> True
- False ->
- # If there is No_Such_Conversion, then `self` and `that` are probably
- # host or polyglot values, so we just compare them with the default comparator.
- eq_self = Panic.catch No_Such_Conversion (Comparable.from self) _-> Default_Comparator
- eq_that = Panic.catch No_Such_Conversion (Comparable.from that) _-> Default_Comparator
- similar_type = Meta.is_same_object eq_self eq_that
- case similar_type of
- False -> False
- True ->
- case Meta.is_same_object eq_self Default_Comparator of
- True -> Comparable.equals_builtin self that
- False ->
- case eq_self.compare self that of
- Ordering.Equal -> True
- _ -> False
+ if Meta.is_same_object self that then True else
+ # If there is No_Such_Conversion, then `self` and `that` are probably
+ # host or polyglot values, so we just compare them with the default comparator.
+ eq_self = Panic.catch No_Such_Conversion (Comparable.from self) _-> Default_Comparator
+ eq_that = Panic.catch No_Such_Conversion (Comparable.from that) _-> Default_Comparator
+ similar_type = Meta.is_same_object eq_self eq_that
+ case similar_type of
+ False -> False
+ True ->
+ case Meta.is_same_object eq_self Default_Comparator of
+ True -> Comparable.equals_builtin self that
+ False ->
+ case eq_self.compare self that of
+ Ordering.Equal -> True
+ _ -> False 2x faster than 1. |
That rapidly decreased performance - #5709 (comment)
I've spent few more hours looking into the IGV graphs as generated by However when I inspect this hot piece of code for |
I created Moreover there are various Truffle compiler options and it turns out the culprit is in InliningRecursionDepth=2. If we set it higher, the diff --git engine/runtime/src/bench/java/org/enso/interpreter/bench/BenchmarksRunner.java engine/runtime/src/bench/java/org/enso/interpreter/bench/BenchmarksRunner.java
index 16954b0282..025f8bcbe6 100644
--- engine/runtime/src/bench/java/org/enso/interpreter/bench/BenchmarksRunner.java
+++ engine/runtime/src/bench/java/org/enso/interpreter/bench/BenchmarksRunner.java
@@ -33,7 +33,7 @@ public class BenchmarksRunner {
*/
public BenchmarkItem run(String label) throws RunnerException, JAXBException {
ChainedOptionsBuilder builder = new OptionsBuilder()
- .jvmArgsAppend("-Xss16M", "-Dpolyglot.engine.MultiTier=false")
+ .jvmArgsAppend("-Xss16M", "-Dpolyglot.engine.MultiTier=false", "-Dpolyglot.engine.InliningRecursionDepth=10")
.include("^" + label + "$");
if (Boolean.getBoolean("bench.compileOnly")) { e.g. looks like @steve-s is right. Our |
@kustosz suggests:
|
Pavel Marek reports a new 🔴 DELAY for today (2023-04-06): Summary: There is 45 days delay in implementation of the If cascades 5x slower than case-of due to limit of recursive inlining (#5709) task. Delay Cause: I have not worked on this issue for a long time. I expect roughly two more days on this issue, if everything goes smoothly. |
Pavel Marek reports a new STANDUP for today (2023-04-06): Progress: Fiddling around with cloning a root node once IfThenElseNode detects that there is another |
Jaroslav Tulach reports a new 🔴 DELAY for today (2023-04-13): Summary: There is 4 days delay in implementation of the If cascades 5x slower than case-of due to limit of recursive inlining (#5709) task. Some progress has been made, PR exists and improves something, but we need more... Delay Cause: Not sure how I managed to set the final day to yesterday, when I only started to work on the issue yesterday? Possible solutions: I need to investigate & try slightly different approach and see if it helps. |
Jaroslav Tulach reports a new STANDUP for yesterday (2023-04-12): Progress: - Discussions about
Next Day: 5x slower if cascade
|
Jaroslav Tulach reports a new STANDUP for yesterday (2023-04-13): Progress: - More than 10x speedup: #6255
Next Day: Check benchmarks and integrated #6255. Improve |
Fixes #5709. We have a test and a generic fix that improves inlining of every builtin. Everything seems to be faster.
Jaroslav Tulach reports a new STANDUP for yesterday (2023-04-14): Progress: - Got merged: if cascade: #6255 - still needs some post-mortem actions
Next Day: Polish
|
Benchmark results of
We can see that the original 5x slowdown is gone. |
Jaroslav Tulach reports a new STANDUP for yesterday (2023-04-15): Progress: - Found problem with
Next Day: Polish EqualsNode for integration |
Jaroslav Tulach reports a new STANDUP for yesterday (2023-04-16): Progress: - how to document code discussion: https://github.com/orgs/enso-org/discussions/6296#discussioncomment-5626754
Next Day: Review benchmarks for
|
During investigation of #5687, we found out that
if-then-else
expressions are roughly 5x slower than theircase-of
equivalents.Tasks
The text was updated successfully, but these errors were encountered: