[Numpy-discussion] seterr changes
tim.hochberg at cox.net
Wed Apr 19 08:58:04 CDT 2006
Hi Travis et al,
I started looking at your seterr changes. I stared at yours for a while
then I stared at mine for a while. Then I decided that mine wouldn't
work right in the presence of threads. Then I decided that yours
wouldn't work right in the presence of threads either. Specifically, it
looks like ufunc_update_use_defaults isn't going to work. I think I know
how to fix that, but I'm not sure that it's worth the trouble since I
also did some benchmarking and it appears that the benefit of special
casing is minimal.
I looked at six cases: small (len-1), medium (len-1e4) and large
(len-1e6) arrays with error checking on and error checking off. For
medium and large arrays, I could discern no difference at all. For small
arrays, there may be some difference, but it appears to be less than 5%.
I'm not sure it's worth working through a bunch of finicky thread stuff
to get just 5% back. If these benchmark numbers hold up I'd be inclined
to rip out the use_default support since it's complicated enough that I
know we'll end up chasing a few evil thread related bugs down through it.
I'll include the benchmarking code below. If people could (a) look it
over and confirm that I'm not doing something bogus and (b) try it on
some different platforms and see if they see a more signifigant
difference, I'd appreciate it.
I'm also curious about the seterr interface. It returns
ufunc_values_obj. I'm wasn't sure how one is supposed to pass that back
in to seterr, so I modified seterr to instead return a dictionary. I
also modified it so that the seterr function itself has no defaults (or
rather they're all None). Instead, any unspecified values are taken from
the current error state. Thus seterr(divide="warn") changes only the
divide state, leaving the other entries alone.
from timeit import Timer
setup = """
a = numpy.zeros([%s], dtype=float)
for size in [1, 10000, 1000000]:
for i in range(3):
for state in ['ignore', 'warn']:
reps = min(100000000 / size, 100000)
timer = Timer("a * a", setup % (state, size))
print "%s|%s =>" % (state, size), timer.timeit(reps)
More information about the Numpy-discussion