Discussing if its worth moving Py/C functions from METH_VARARGS to METHO when they only recieve 1 argument on the PyGame mailing list. Crossposting here since some of you might be interested in the results.
tested different ways to evaluate args to see how much speed difference there was
- 10,000,000 tests, python 2.6 on 32bit arch linux
- included a pass and NOARGS metrhod to see the difference in overhead of the loop and parsing an arg compared to running a method with no args.
---- output pass 1.85659885406 METH_NOARGS 3.24079704285 METH_O 3.66321516037 METH_VARARGS 6.09881997108 METH_KEYWORDS 6.037307024 METH_KEYWORDS (as keyword) 10.9263861179
------- Python Script, (used blender module for testing)
import time
from Blender.sys import test_METHO, test_METH_VARARGS, test_METH_KEYWORDS, test_METH_NOARGS
RUN = 10000000
t = time.time() for i in xrange(RUN): pass print 'pass', time.time()-t
t = time.time() for i in xrange(RUN): test_METH_NOARGS() print 'METH_NOARGS', time.time()-t
t = time.time() for i in xrange(RUN): test_METHO(1) print 'METH_O', time.time()-t
t = time.time() for i in xrange(RUN): test_METH_VARARGS(1) print 'METH_VARARGS', time.time()-t
t = time.time() for i in xrange(RUN): test_METH_KEYWORDS(1) print 'METH_KEYWORDS', time.time()-t
t = time.time() for i in xrange(RUN): test_METH_KEYWORDS(val=1) print 'METH_KEYWORDS (as keyword)', time.time()-t
------------------- C functions
static PyObject *test_METHO( PyObject * self, PyObject * value ) { int val = (int)PyInt_AsLong(value);
if( val==-1 && PyErr_Occurred() ) {
PyErr_SetString(PyExc_AttributeError, "not an int");
return NULL;
}
Py_RETURN_NONE;
}
static PyObject *test_METH_VARARGS( PyObject * self, PyObject * args ) { int val;
if( !PyArg_ParseTuple( args, "i", &val ) )
return NULL;
Py_RETURN_NONE;
}
static PyObject *test_METH_KEYWORDS( PyObject * self, PyObject * args, PyObject *kwd) { int val; static char *kwlist[] = {"val", NULL};
if( !PyArg_ParseTupleAndKeywords(args, kwd, "i", kwlist, &val) )
return NULL;
Py_RETURN_NONE;
}
static PyObject *test_METH_NOARGS( PyObject * self, PyObject * args ) { Py_RETURN_NONE; }
struct PyMethodDef M_sys_methods[] = { {"test_METHO", test_METHO, METH_O, ""}, {"test_METH_KEYWORDS", test_METH_KEYWORDS, METH_KEYWORDS, ""}, {"test_METH_NOARGS", test_METH_NOARGS, METH_NOARGS, ""}, {"test_METH_VARARGS", test_METH_VARARGS, METH_VARARGS, ""}, {NULL, NULL, 0, NULL} };
--
- Campbell