-
-
Notifications
You must be signed in to change notification settings - Fork 205
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
More rule tweaks #1567
More rule tweaks #1567
Conversation
@TiagoCavalcante Looks good - thanks. But before we merge would you do a benchmark on mathics-benchmarks on this? I suspect the time difference will be small, but I'd be interested all the same. |
The results were very weird. Before:
After:
Shouldn't |
Why not write some benchmarks to check this or try to isolate this? I am guessing that one can write Mathics definitions with the two kinds of type checking. And also we can change the Python code - maybe add another builtin temporarily testing the alternative way on simple primitives (and then more complex ones...) I am not surprised though that we are surprised. If we knew this stuff perfectly we probably would be having fewer problems. |
For a short string:
For the same string stored in a variable:
For a plane symbol:
For real numbers:
For a "complicate" expression
|
@@ -487,7 +487,7 @@ class NextPrime(Builtin): | |||
} | |||
|
|||
def apply(self, n, k, evaluation): |
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.
Try this instead:
def apply(self, n, k, evaluation):
"NextPrime[n_, k_Integer]"
py_k = k.to_python(n_evaluation=evaluation)
py_n = n.to_python(n_evaluation=evaluation)
if type(py_k) is not int or type(py_n):
return
This should do the same trick, without the overhead in the pattern matching.
mathics/builtin/physchemdata.py
Outdated
@@ -123,7 +123,7 @@ def apply_all_properties(self, evaluation): | |||
return from_python(sorted(_ELEMENT_DATA[0])) | |||
|
|||
def apply_name(self, name, prop, evaluation): | |||
"ElementData[name_?StringQ, prop_]" | |||
"ElementData[name_String, prop_]" |
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.
Same thing:
def apply_name(self, name, prop, evaluation):
"ElementData[name_, prop_]"
if not isinstance(name, String):
return
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 like pattern matching, but if performance doesn't, we should obey it.
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.
@mmatera I'm thinking, why does pattern matching have a so big overhead? Doesn't it just test against a type and get a specific function for that type? If yes, why the overhead is so big?
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 repaired that there isn't System`String
in quick_pattern_test
.
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.
@mmatera I'm thinking, why does pattern matching have a so big overhead? Doesn't it just test against a type and get a specific function for that type? If yes, why the overhead is so big?
It is not specifically pattern matching although that may have its own specific slowness. It is any function call of which pattern matching is one kind.
This is the kind of thing we need to study and improve. Specific details and data can be found in #1568 (comment) We need to study that and try things to fix it.
This could be also useful:
|
Thanks for the benchmarks @mmatera! I hadn't time to do them, and probably they won't be as complete as yours. |
…/Mathics into quickpatterntest
My take is on this data is that basically the overhead difference is about the same for everything. When you get to expressions though the overhead in function calls swamps differences there are in pattern matching - this is taking 10 times longer and other tests show that this is not in computation time. So again we need to focus on function calls. |
The problem here is that, from the WL side, function calls are just pattern matching, and pattern matching is expensive because it involves many Python function calls, which at the time are very expensive. So, anything we can do to reduce the number of Python function calls will improve the performance. |
It is a problem, but not the only problem and I am concerned about confusing the pattern matching and Mathics function calls. A Mathics function call involves not just potentially several pattern-match signatures until one that succeeds, (or all signatures exhausted), but there are iteration and recursion checks, and checks to see if there was a rewrite rule instead of a function call, and if so the process repeats. And once a rule matches, there is argument substitution before the call. I used to think (and still do) that Python method calls were expensive because methods need to constantly be resolved as a result of its OO behavior and ability to change that at run time. However Mathics can be an order of magnitude worse. One plan of attack at least for built-in functions and then later possibly for compiled functions is to hold on to the found pattern-to-apply-method map for a particular call site and use that avoiding the entire lookup process. As the trend has now been to do the checking in Python, we will also detect mismatches when there are mistakes. Take for example this code that is in a recent PR:
which is found in the implementation of built-in With this, something the code for NonPositive might look like:
where |
Why are the two sets of SHA's the same? |
My mistake, I forgot to checkout to master before running the tests. I'll add this to mathics-benchmark and re-run the tests latter. And run black too. |
New benchmarks:
|
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.
Merging in so we can test...
No description provided.