在我的(slow ish;-)第一天MacBook Air,1.6GHz Core 2 Duo,MacOSX 10.5上的System python 2.5上,将代码保存在
op.py
我看到以下时间安排:
$ python -mtimeit -s'import op' 'op.f1()'
10 loops, best of 3: 5.58 sec per loop
$ python -mtimeit -s'import op' 'op.f2()'
10 loops, best of 3: 3.15 sec per loop
所以,我的机器比你的慢了1.9倍。
我对这项任务最快的代码是:
def f3(x=x,y=y,n=n,z=z):
rows = [[0]*y for i in range(x)]
rr = random.randrange
inc = (1).__add__
sat = (0xff).__and__
for i in range(n):
inputX, inputY = rr(x), rr(y)
b = max(0, inputX - z)
t = min(inputX + z, x)
l = max(0, inputY - z)
r = min(inputY + z, y)
for i in range(b, t):
rows[i][l:r] = map(inc, rows[i][l:r])
for i in range(x):
rows[i] = map(sat, rows[i])
什么时候:
$ python -mtimeit -s'import op' 'op.f3()'
10 loops, best of 3: 3 sec per loop
所以,一个非常温和的加速,在你的机器上投射到超过1.5秒-远高于你的目标1.0:-(。
使用简单的C代码扩展,
exte.c
……
#include "Python.h"
static PyObject*
dopoint(PyObject* self, PyObject* args)
{
int x, y, z, px, py;
int b, t, l, r;
int i, j;
PyObject* rows;
if(!PyArg_ParseTuple(args, "iiiiiO",
&x, &y, &z, &px, &py, &rows
))
return 0;
b = px - z;
if (b < 0) b = 0;
t = px + z;
if (t > x) t = x;
l = py - z;
if (l < 0) l = 0;
r = py + z;
if (r > y) r = y;
for(i = b; i < t; ++i) {
PyObject* row = PyList_GetItem(rows, i);
for(j = l; j < r; ++j) {
PyObject* pyitem = PyList_GetItem(row, j);
long item = PyInt_AsLong(pyitem);
if (item < 255) {
PyObject* newitem = PyInt_FromLong(item + 1);
PyList_SetItem(row, j, newitem);
}
}
}
Py_RETURN_NONE;
}
static PyMethodDef exteMethods[] = {
{"dopoint", dopoint, METH_VARARGS, "process a point"},
{0}
};
void
initexte()
{
Py_InitModule("exte", exteMethods);
}
(注:我没有仔细检查过——我认为它不会因为引用窃取和借用的正确相互作用而泄漏内存,但在投入生产之前应该仔细检查代码;—),我们可以这样做。
import exte
def f4(x=x,y=y,n=n,z=z):
rows = [[0]*y for i in range(x)]
rr = random.randrange
for i in range(n):
inputX, inputY = rr(x), rr(y)
exte.dopoint(x, y, z, inputX, inputY, rows)
时机
$ python -mtimeit -s'import op' 'op.f4()'
10 loops, best of 3: 345 msec per loop
显示了8-9倍的加速度,这将使你进入你想要的球场。我看到一条评论说你不想要任何第三方扩展,但是,好吧,这个小小的扩展你可以完全自己做;-)。(不确定什么许可条件适用于堆栈溢出时的代码,但如果您需要,我很高兴在Apache2许可证或类似许可证下重新发布它;-)。