From: Scott D. D. <Sco...@Ac...> - 2007-12-30 21:52:51
|
Bruce Sherwood wrote: > In a test version not yet released I've implemented essentially the > scheme suggested by Scott David Daniels, and it works very well. Thanks! > > I found by timing measurements that a faster scheme with less penalty > for the case of sqrt(array) looks like this: > > def sqrt(x): > if type(x) is float: return mathsqrt(x) > return numpysqrt(x) > > This scheme not only solves the problem but actually yields faster > square roots of scalar arguments than numpy, by about a factor of 3. So > what was conceived as a workaround is actually a performance enhancement. I actually did a bit of timing before I suggested the try/except version. I use subclasses of ints and floats in some of the code I write. A simple example (to make values more obvious): class Float(float): def __repr__(self): return '%s(%s)' % (self.__class__.__name__, float.__repr__(self)) class Meters(Float): pass class Grams(Float): pass ... Then I can make physical constants a little more obvious interactively. My first version was: def sqrt(x): if isinstance(x, (int, long, float)): return mathsqrt(x) else: return numpysqrt(x) I then realized math.sqrt was already doing this check. Since the check is already there, I decided not to slow down the more common scalar case. That was when I switched to the "try: ... except TypeError: ..." form (to use math.sqrt's type checks). I then made sure performance on a short (ten-element) vector was not too severely impacted. If you still want to exact match on types, I'd suggest accepting at least floats and ints, since you'll otherwise get performance reports about how much slower sqrt(4) is than sqrt(4.0). Something more like: def sqrt(x): t = type(x) if t is float or t is int: return mathsqrt(x) else: return numpysqrt(x) --Scott David Daniels Sco...@Ac... |