| | 8 | }}} |
| | 9 | As Travis explained, some overhead is expected because {{{x.sum(0)}}} calls DOUBLE_add 500 times instead of 1 for {{{x[0]+x[1]}}}, but in Numeric 24.1 overhead was much smaller: |
| | 10 | {{{ |
| | 11 | > python -m timeit -s "from Numeric import zeros,sum; x = zeros((2,500),'f')" "sum(x)" |
| | 12 | 100000 loops, best of 3: 6.05 usec per loop |
| | 13 | > python -m timeit -s "from Numeric import zeros,sum; x = zeros((2,500),'f')" "x[0]+x[1]" |
| | 14 | 100000 loops, best of 3: 3.63 usec per loop |
| | 15 | }}} |
| | 17 | Numeric 24.1 inner loop (ufuncobject.c:613-627): |
| | 18 | {{{ |
| | 19 | /* This is the inner loop to actually do the computation. */ |
| | 20 | loop=-1; |
| | 21 | while(1) { |
| | 22 | while (loop < n_loops-2) { |
| | 23 | loop++; |
| | 24 | loop_i[loop] = 0; |
| | 25 | for(i=0; i<self->nin+self->nout; i++) { resets[loop][i] = pointers[i]; } |
| | 26 | } |
| | 27 | |
| | 28 | function(pointers, loop_n+(n_loops-1), steps[n_loops-1], data); |
| | 29 | |
| | 30 | while (loop >= 0 && !(++loop_i[loop] < loop_n[loop]) && loop >= 0) loop--; |
| | 31 | if (loop < 0) break; |
| | 32 | for(i=0; i<self->nin+self->nout; i++) { pointers[i] = resets[loop][i] + steps[loop][i]*loop_i[loop]; } |
| | 33 | } |
| | 35 | |
| | 36 | Numpy r2208 inner loop (ufuncobject.c:1968-1985): |
| | 37 | {{{ |
| | 38 | while(loop->index < loop->size) { |
| | 39 | /* Copy first element to output */ |
| | 40 | if (loop->obj) |
| | 41 | Py_INCREF(*((PyObject **)loop->it->dataptr)); |
| | 42 | memmove(loop->bufptr[1], loop->it->dataptr, |
| | 43 | loop->outsize); |
| | 44 | /* Adjust input pointer */ |
| | 45 | loop->bufptr[0] = loop->it->dataptr+loop->steps[0]; |
| | 46 | loop->function((char **)loop->bufptr, |
| | 47 | &(loop->N), |
| | 48 | loop->steps, loop->funcdata); |
| | 49 | UFUNC_CHECK_ERROR(loop); |
| | 50 | |
| | 51 | PyArray_ITER_NEXT(loop->it) |
| | 52 | loop->bufptr[1] += loop->outsize; |
| | 53 | loop->bufptr[2] = loop->bufptr[1]; |
| | 54 | loop->index++; |
| | 55 | } |
| | 56 | }}} |