On Fri, Nov 08, 2013 at 10:19:30AM +0100, Armin Rigo wrote: > I fear a bit that *all* cases are on the clearly nonsense side of things. > I don't particularly think there is code out there that would see any > speed-ups using these cases. As Amaury pointed out this introduces > delicate correctness issues, and for maybe nothing... :-/ I can be > convinced of the countrary though.
The fairly unlikely ones are cheap and easy to verify, so it's arguable as to whether they're worth worrying about. We can drop some or all if we wish. The ones that I'm much more sure are a win are checking for one type of number in a list of another type. In essence, this patch makes the performance of intermingling number types considerably less surprising than before. For example, the patch doubles the speed of checking for an int in a list of floats and makes looking up a long in a list of ints 10x faster. In my experience, Python programs that nominally use floats actually end up slinging lots of integers around since very few people can be bothered to write "x = 1.0" instead of "x = 1". I expect the other types are similarly intermingled in many programs. The original benchmark I created wasn't as clear as it could have been about this, so I've redone the figures with performance differences so you can easily see how performance is affected. I've also tweaked the benchmark to be sure that there was no possibility of the JIT warming up half-way through (which doesn't seem to have happened, but better safe than sorry). Pre-patch: ===> Integer lists 1 in l: 13.998 's' in l: 21.191 0 in l: 0.001 1.0 in l: 45.065 1L in l: 140.420 object() in l: 21.169 t1() in l: 28.889 t2() in l: 373.511 ===> Float lists 1 in l: 34.217 's' in l: 93.441 0.8 in l: 0.000 1.0 in l: 18.741 1L in l: 188.214 object() in l: 145.564 t1() in l: 336.450 t2() in l: 373.866 Post-patch (with approximate performance differences): ===> Integer lists 1 in l: 14.020 [1x] 's' in l: 0.001 [near inf x] 0 in l: 0.001 [no difference] 1.0 in l: 14.033 [3.2x] 1L in l: 14.036 [10x] object() in l: 0.002 [near inf x] t1() in l: 34.778 [0.83x] t2() in l: 278.776 [1.33x] ===> Float lists 1 in l: 18.768 [1.8x] 's' in l: 0.000 [near inf x] 0.8 in l: 0.000 [no difference] 1.0 in l: 18.773 [1x] 1L in l: 18.779 [10x] object() in l: 0.000 [near inf x] t1() in l: 246.722 [1.36x] t2() in l: 278.489 [1.34x] One interesting thing that this shows is the apparent lack of performance of symmetry between comparing ints and floats vs. comparing floats and ints. Laurie
import time class t1(object): def __eq__(self, o): return o == 1 class t2(object): def __eq__(self, o): return o == 1.0 def bench(l, exp, f, i): t = time.time() for _ in range(2000): f() if i == 1: print "%s: %.3f" % (exp, time.time() - t) print "===> Integer lists" for i in range(2): l = [] if i == 0: s = 2000 else: s = 10000000 for j in range(s): l.append(0) l.append(1) bench(l, "1 in l", lambda: 1 in l, i) bench(l, "'s' in l", lambda: 's' in l, i) bench(l, "0 in l", lambda: 0 in l, i) bench(l, "1.0 in l", lambda: 1.0 in l, i) bench(l, "1L in l", lambda: 1L in l, i) bench(l, "object() in l", lambda: object() in l, i) bench(l, "t1() in l", lambda: t1() in l, i) bench(l, "t2() in l", lambda: t2() in l, i) print "===> Float lists" for i in range(2): l = [] if i == 0: s = 2000 else: s = 10000000 for j in range(s): l.append(0.8) l.append(1.0) bench(l, "1 in l", lambda: 1 in l, i) bench(l, "'s' in l", lambda: 's' in l, i) bench(l, "0.8 in l", lambda: 0.8 in l, i) bench(l, "1.0 in l", lambda: 1.0 in l, i) bench(l, "1L in l", lambda: 1L in l, i) bench(l, "object() in l", lambda: object() in l, i) bench(l, "t1() in l", lambda: t1() in l, i) bench(l, "t2() in l", lambda: t2() in l, i)
_______________________________________________ pypy-dev mailing list pypy-dev@python.org https://mail.python.org/mailman/listinfo/pypy-dev