From: Bruce S. <Bru...@nc...> - 2007-12-31 19:21:16
|
I repeated my own timings and then remembered why I didn't use try/except. The try/except scheme does give the fastest square root of a scalar (1.2 microsec on my 1 GHz laptop) but doubles the time for sqrt(array([1,2,3,4,5,6,7,8,9,10])), from about 10 microsec to about 20 microsec. So I've settled for the following, which gives sqrt(scalar) of 1.7 microsec and almost no change in sqrt(array): def sqrt(x): t = type(x) if t is float or t is int or t is long: return _m_sqrt(x) return _n_sqrt(x) Thanks again for thinking about this issue, and for alerting me to check not just for float. Bruce Sherwood P.S. What's in the just-released 4.beta22 only checks for float, but the correction is now in CVS. Scott David Daniels wrote: > 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... > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2005. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Visualpython-users mailing list > Vis...@li... > https://lists.sourceforge.net/lists/listinfo/visualpython-users > |