|
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
>
|