3 ms·
When it says that "argument passing" was responsible for 31% of the time, do I understand right that we're talking about this line in the inner loop? str(i
by anentropic 6y ago
When it says that "argument passing" was responsible for 31% of the time, do I understand right that we're talking about this line in the inner loop?
str(i)
...and the time is spent packing i into a tuple (i,) and then unpacking it again?
are keyword args faster? or they do the same but via dict instead of tuple I guess
- kmod 6y agoYep! It's slightly worse than you would think. Here's a (slightly edited) version of how the argument passing works static PyObject * unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *x = NULL; static char *kwlist[] = {"object", "encoding", "errors", 0}; char *encoding = NULL; char *errors = NULL; PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:str", kwlist, &x, &encoding, &errors)) } Notice the call to PyArg_ParseTupleAndKeywords -- it takes an arguments tuple and a format string and executes a mini interpreter to parse the arguments from the tuple. It has to be ready to receive arguments as any combination of keywords and positional, but for a given callsite the matching will generally be static.
- anentropic 6y agoAnd is that literally every Python function doing that under the hood? Even a 1-arity function? I don't get what the format string is for. Anyway, thanks for answering!
- kmod 6y agoIt used to be this way, but at some point they added a faster calling convention and moved a number of things to it. Calling type objects still falls back to the old convention though.