-
-
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
No reevaluation of evaluated values #391
Conversation
Can you run |
@@ -1103,6 +1113,9 @@ def replace_vars(self, vars, options=None, | |||
leaves = [Expression('List', *func_params), body] + \ | |||
self.leaves[2:] | |||
|
|||
if len(vars) == 0: # might just be a symbol set via Set[] we looked up here |
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.
Why len(vars) == 0
instead of not vars
?
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.
Good point, I wasn't even aware that not
could be used in this way on a dict here. Changed that.
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.
benchmark.py
seems to give a very slight across the board improvement of 2-4%, but it could be as well random noise. I think it really only affects the special case of looking up a symbol that's expensive to compute.
EDIT I looked at best, when I should have looked at avg. Now it seems more like 10% to 15% improvement. Here are the values:
EVALUATION BENCHMARKS (WITH PR CHANGE):
Arithmetic
'1 + 2'
5000 loops, avg: 227 us per loop, best: 209 us per loop
'5 * 3'
5000 loops, avg: 246 us per loop, best: 223 us per loop
DensityPlot
'DensityPlot[x + y^2, {x, -3, 3}, {y, -2, 2}]'
5 loops, avg: 489 ms per loop, best: 378 ms per loop
Expand
'Expand[(a1+a2)^200]'
5 loops, avg: 424 ms per loop, best: 328 ms per loop
'Expand[(a1+a2+a3)^25]'
5 loops, avg: 883 ms per loop, best: 695 ms per loop
'Expand[(a1+a2+a3+a4+a5+a6+a7)^3]'
10 loops, avg: 152 ms per loop, best: 125 ms per loop
Matrix
'RandomInteger[{0,1}, {10,10}] . RandomInteger[{0,1}, {10,10}]'
5 loops, avg: 403 ms per loop, best: 315 ms per loop
'RandomInteger[{0,10}, {10,10}] + RandomInteger[{0,10}, {10,10}]'
100 loops, avg: 38.4 ms per loop, best: 35.8 ms per loop
Plot
'Plot[0, {x, -3, 3}]'
100 loops, avg: 92.4 ms per loop, best: 87.7 ms per loop
'Plot[x^2 + x + 1, {x, -3, 3}]'
5 loops, avg: 820 ms per loop, best: 664 ms per loop
'Plot[Sin[Cos[x^2]], {x, -3, 3}]'
5 loops, avg: 2.46 s per loop, best: 2.03 s per loop
'Plot[Sin[100 x], {x, -3, 3}]'
5 loops, avg: 1.75 s per loop, best: 1.43 s per loop
Plot3D
'Plot3D[0, {x, -1, 1}, {y, -1, 1}]'
5 loops, avg: 264 ms per loop, best: 205 ms per loop
'Plot3D[x + y^2, {x, -3, 3}, {y, -2, 2}]'
5 loops, avg: 822 ms per loop, best: 639 ms per loop
'Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -3, 3}]'
5 loops, avg: 2.55 s per loop, best: 2.08 s per loop
'Plot3D[Sin[100 x + 100 y ^ 2], {x, 0, 1}, {y, 0, 1}]'
5 loops, avg: 2.83 s per loop, best: 2.14 s per loop
Random
'RandomInteger[{-100, 100}, 100]'
1000 loops, avg: 5.82 ms per loop, best: 3.94 ms per loop
'RandomInteger[10, {10, 10}]'
1000 loops, avg: 5.83 ms per loop, best: 4.59 ms per loop
'RandomInteger[{0,1}, {5, 5, 5}]'
1000 loops, avg: 7.77 ms per loop, best: 6.22 ms per loop
'RandomReal[1, 100]'
1000 loops, avg: 7.88 ms per loop, best: 6.37 ms per loop
'RandomReal[{-1, 1}, 100]'
1000 loops, avg: 7.57 ms per loop, best: 6.21 ms per loop
'RandomComplex[2 + I, 50]'
100 loops, avg: 37.1 ms per loop, best: 29.5 ms per loop
'RandomComplex[{-1 - I, 1 + I}, {10, 10}]'
100 loops, avg: 65.9 ms per loop, best: 58.6 ms per loop
Trig
'Sin[RandomReal[]]'
1000 loops, avg: 1.97 ms per loop, best: 1.67 ms per loop
'ArcTan[RandomReal[]]'
1000 loops, avg: 1.79 ms per loop, best: 1.55 ms per loop
EVALUATION BENCHMARKS (WITHOUT PR CHANGE):
Arithmetic
'1 + 2'
5000 loops, avg: 236 us per loop, best: 210 us per loop
'5 * 3'
5000 loops, avg: 289 us per loop, best: 226 us per loop
DensityPlot
'DensityPlot[x + y^2, {x, -3, 3}, {y, -2, 2}]'
5 loops, avg: 492 ms per loop, best: 370 ms per loop
Expand
'Expand[(a1+a2)^200]'
5 loops, avg: 471 ms per loop, best: 373 ms per loop
'Expand[(a1+a2+a3)^25]'
5 loops, avg: 1.02 s per loop, best: 765 ms per loop
'Expand[(a1+a2+a3+a4+a5+a6+a7)^3]'
10 loops, avg: 173 ms per loop, best: 132 ms per loop
Matrix
'RandomInteger[{0,1}, {10,10}] . RandomInteger[{0,1}, {10,10}]'
5 loops, avg: 447 ms per loop, best: 353 ms per loop
'RandomInteger[{0,10}, {10,10}] + RandomInteger[{0,10}, {10,10}]'
100 loops, avg: 42.3 ms per loop, best: 36.1 ms per loop
Plot
'Plot[0, {x, -3, 3}]'
10 loops, avg: 118 ms per loop, best: 89.5 ms per loop
'Plot[x^2 + x + 1, {x, -3, 3}]'
5 loops, avg: 833 ms per loop, best: 663 ms per loop
'Plot[Sin[Cos[x^2]], {x, -3, 3}]'
5 loops, avg: 2.76 s per loop, best: 2.26 s per loop
'Plot[Sin[100 x], {x, -3, 3}]'
5 loops, avg: 1.86 s per loop, best: 1.49 s per loop
Plot3D
'Plot3D[0, {x, -1, 1}, {y, -1, 1}]'
5 loops, avg: 287 ms per loop, best: 216 ms per loop
'Plot3D[x + y^2, {x, -3, 3}, {y, -2, 2}]'
5 loops, avg: 859 ms per loop, best: 641 ms per loop
'Plot3D[Sin[x + y^2], {x, -3, 3}, {y, -3, 3}]'
5 loops, avg: 2.74 s per loop, best: 2.16 s per loop
'Plot3D[Sin[100 x + 100 y ^ 2], {x, 0, 1}, {y, 0, 1}]'
5 loops, avg: 2.85 s per loop, best: 2.19 s per loop
Random
'RandomInteger[{-100, 100}, 100]'
1000 loops, avg: 4.73 ms per loop, best: 3.99 ms per loop
'RandomInteger[10, {10, 10}]'
1000 loops, avg: 6.18 ms per loop, best: 4.64 ms per loop
'RandomInteger[{0,1}, {5, 5, 5}]'
1000 loops, avg: 7.21 ms per loop, best: 6.28 ms per loop
'RandomReal[1, 100]'
1000 loops, avg: 7.26 ms per loop, best: 6.39 ms per loop
'RandomReal[{-1, 1}, 100]'
1000 loops, avg: 6.87 ms per loop, best: 6.23 ms per loop
'RandomComplex[2 + I, 50]'
100 loops, avg: 32.6 ms per loop, best: 29.6 ms per loop
'RandomComplex[{-1 - I, 1 + I}, {10, 10}]'
100 loops, avg: 63.6 ms per loop, best: 59.5 ms per loop
Trig
'Sin[RandomReal[]]'
1000 loops, avg: 1.78 ms per loop, best: 1.7 ms per loop
'ArcTan[RandomReal[]]'
1000 loops, avg: 1.65 ms per loop, best: 1.57 ms per loop
…plain what's going on here
Mathics currently reevaluates variable values (i.e. values of symbols set via Set[]) every time they're accessed.
This can lead to some worrisome performance (and it gets worse for even longer lists):
x=Range[10000]; Timing[First[x]]
{0.2507470000000005,1}
This PR fixes this by not rebuilding expressions if no var is replaced. That way, the original expression's is_evaluated attribute does not get reset, and the expression is thus not reevaluated when Expression.evaluate() gets called for it later on. With change in PR:
x=Range[10000]; Timing[First[x]]
{0.08288399999999996,1}