-
Notifications
You must be signed in to change notification settings - Fork 903
Aggressively try to use Integers for arithmetic #1563
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
Conversation
|
Afraid I'm not able to try this out in the environment where I use Rhino, but I'm OK if the Rhino integration would break if it wrongfully expects Doubles, instead of Numbers... Do wonder about whether this PR is in any way related to #350 or (parts of) #717 & #507, in the sense of whether those cases are (partly) resolved/changes by this PR or whether those cases give hints for possible further optimizations in the int/double area Specifically for #350 I think this PR will just result in Java receiving an int more often, correct? I think #350 can just be closed as Won't Fix, as Java integration code should not expect Doubles, but Numbers. Agree? Also a question: in #350 (comment) you mentioned there being an integer optimization on optLevel 9. Is that (still?) really the case? I never found any code in Rhino that does anything different between optLevel 1 and 9 |
|
sorry.... |
|
@gbrail spend some time to give this a try by applying to core-js. I had one issue to fix - my Reflect/Proxy impl (see #1431) uses instanceof Double at two places in NativeReflect. After fixing that all my tests are running fine. Maybe other products extending Rhino in some ways and also depending on the assumption that every numbers a double internally. But for me that is fine, i guess i know what happens and a have a large test suite to check the compatibility. Summary: i'm fine with this |
When doing math, try to do integer arithmetic when the arguments passed are Integer objects, rather than always falling back to floating-point math. This speeds up some benchmarks that rely heavily on integer arithmetic.
8634af5 to
4e1ae12
Compare
|
@gbrail We just updated Rhino and this change broke one of our tests, which is not critical for us, but Rhino behavior seemed unexpected, so I would like to raise the concern for this specific case: Then the first invocation below will pass, but the second - will fail, as the NativeArray parameter contains unexpected mix of Integers and doubles: |
|
Can you open an issue for this? Hard to keep up with comments on closed PRs. I'm not sure what part of your example there is JavaScript and what parts are Kotlin or something else, but in general, a JavaScript function that would typically be expected to return a "number" might return different types of numbers, and internal optimizations may change that specific type, for example if we can do the work using only integers we will. This is probably worth an update to the docs (which need a big update anyway!) The best practice for calling JavaScript from non-JavaScript in Rhino is to not assume this, and to at least use the various functions of Number like intValue() and doubleValue() if you need a primitive. And in fact, if you are writing truly general-purpose code, you can't assume anything about what comes back from a function written in JS, and if you care you should use a method like ScriptRuntime.toNumber() which can handle most things. Finally, maybe one of the folks on the project who works on the various reflection-based embeddings would have a different view, since I get the impression that's what you're trying to do here. |
|
Thanks Greg, Yes you got it right and this answers all my questions. I'll open an issue as you asked. |
This PR changes some of the logic that does arithmetic using Number objects to try and do integer arithmetic when both operands are integers, rather than assuming that all arithmetic should be done using floating-point.
This also changes a few fundamental constants -- for example, Rhino has always defined "zero" as "0.0" but this PR makes it truly "0".
If Rhino embedders are assuming that all numbers coming back from Rhino are Double objects (rather than checking for Number and then getting either intValue() or doubleValue() as they need), then their code may break. I had to change a few test cases for this reason. If, on the other hand, embedders are working with Number, there should not be an issue.
Some math-heavy benchmarks, like some of the V8 and SunSpider benchmarks, run quite a bit faster with this change.
I would be interested to see if some people have code that breaks because of this, so I'm hoping that a few of you could try it out -- there are likely other optimizations along these lines that are possible if it works.