Brian Fisher wrote: > I love vector classes with operator overloading... I couldn't stand to > code without them (even though in python, it means there's probably a > lot of object allocation and function calls for simple vector math, > wasting performance). Code is just so much shorter & more readable > with them. I know that I pay for it in performance to use them, and I > know the one I use isn't the best performing one... I'll just wait to > care about that when it's a real problem. I did some back-of-the-envelope benchmarking of various implementations of Vector operations. Attached is the program that I used. My findings were: - Numeric is faster than map is faster than a list comprehension - explicitly storing two variables is even faster (not shown) - using functions from the operator module is faster than built-in math operators - tuples seem to be a little faster to iterate over than lists And some vector-unrelated findings: - function calls are faster than method calls - accessing a bound method is slower than accessing an instance variable In benchmarking my game, I found that I was creating a *lot* of new vector objects, and this does things to your performance. For this reason my vectors are not immutable, but take advantage of in-place operations to conserve objects. I found that it was rare that I needed to access individual elements of a vector, but implemented __iter__ by returning iter([x, y]). This was "good enough" and pretty straightforward. Ethan
s = '''from operator import sub def add1(v1, v2): return [a + b for (a, b) in zip(v1, v2)] def sub1(v1, v2): return [a - b for (a, b) in zip(v1, v2)] def sub2(v1, v2): return [sub(a,b) for (a, b) in zip(v1, v2)] def sub3(v1, v2): return map(sub, v1, v2) v1a = [4.2, 5.4] v1b = [12.0, -4.1] v2a = (4.2, 5.4) v2b = (12.0, -4.1)''' import timeit t = timeit.Timer() print 'baseline', t.repeat() for i in ['sub1', 'sub2', 'sub3']: for j in [1, 2]: t = timeit.Timer('a = %s(v%da,v%db)'%(i,j,j), s) print i, j, t.repeat() s2 = '''import Numeric def sub4(v1, v2): return Numeric.subtract(v1, v2) v1a = Numeric.array([4.2, 5.4]) v1b = Numeric.array([12.0, -4.1])''' t = timeit.Timer('a = sub4(v1a, v1b)', s2) print 'numeric', t.repeat() s3 = ''' class C(object): x = None def __init__(self): pass def f(self, o2): pass def g(self): pass def f(o1, o2): pass o1 = C() o2 = C()''' for i in ['o1.f(o2)', 'C.f(o1, o2)', 'f(o1, o2)']: t = timeit.Timer(i, s3) print i, t.repeat() for i in ['o1.x', 'o1.g', 'o1.g()']: t = timeit.Timer(i, s3) print i, t.repeat()
Attachment:
signature.asc
Description: OpenPGP digital signature