Thanks, Victor. That's very helpful. So RETURN_NONE (and probably RETURN_SMALL_CONST) are not worth it, based on your empirical tests. Your patch shows how (relatively) straight-forward it is to test out new opcodes.
I'm still optimistic about the value of COMPARE_IS_NONE and COMPARE_IS_NOT_NONE, though. Mainly because I've done a quick expansion of LOAD_CONST(None) + COMPARE_OP and it's quite a bit more code and many more instructions than COMPARE_IS_NONE would be: LOAD_CONST(None) COMPARE_OP PyObject *value = ((PyTupleObject *)(consts))->ob_item[oparg]; value->ob_refcnt++; *stack_pointer++ = value; FAST_DISPATCH(); PyObject *right = *--stack_pointer; PyObject *left = stack_pointer[-1] // cmp_outcome(), presumably inlined int r = 0; switch (compare_oparg) { case PyCmp_IS: r = (left == right); break; case PyCmp_IS_NOT: r = (left != right); break; case ... } PyObject *res = r ? Py_True : Py_False; res->ob_refcnt++; if (--(left)->ob_refcnt == 0) _Py_Dealloc(left); if (--(right)->ob_refcnt == 0) _Py_Dealloc(right); stack_pointer[-1] = res; if (res == NULL) goto error; PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); COMPARE_IS_NONE PyObject* left = stack_pointer[-1]; // TOP() PyObject* res = (left == Py_None) ? Py_True : Py_False; res->ob_refcnt++; if (--(left)->ob_refcnt == 0) _Py_Dealloc(left); stack_pointer[-1] = res; // SET_TOP(res) PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); You don't have to get the const arg, there are fewer increfs/decrefs, you skip a pop, you don't have to test res==NULL (because it's Py_True or Py_False, which are never NULL), and if there are separate COMPARE_IS_NONE and COMPARE_IS_NOT_NONE you don't have to switch on the compare arg (though I'm not sure if that part will be worth it). For reference, based on a grep, " is None" occurs 2737 times in the CPython source tree, and " is not None" 2010 times. And I know personally I often use them in loops as well is at the start of functions (for mutable default arg handling). Still, the performance proof will be in the pudding! I might hack these two opcodes together and test it at some point. -Ben On Thu, May 25, 2017 at 6:47 AM, Victor Stinner <victor.stin...@gmail.com> wrote: > Hi Ben, > > I am not convinced that combining operations will have a significant > impact in term of performance. Mark Shanon implemented that in his HotPy > project. > > I proposed a RETURN_NONE opcode to combine LOAD_CONST with RETURN_VALUE. > The issue was rejected because I failed to show any speedup. > > https://bugs.python.org/issue28800 > > I would be interested to restart/finish my registervm project to use > register-based bytecode. It allows to implement more optmisations and > reduce the number of instructions. In my experience, less instructions = > faster code. > > http://faster-cpython.readthedocs.io/registervm.html > > Mark's bytecode uses registers but also a stack. > > Victor > > Le 24 mai 2017 8:09 PM, "Ben Hoyt" <benh...@gmail.com> a écrit : > >> Hi folks, >> >> I was looking at some `dis` output today, and I was wondering if anyone >> has investigated optimizing Python (slightly) by adding special-case >> bytecodes for common expressions or statements involving constants? >> >> For example, I (and, based on a quick grep of the stdlib, many others) >> write "x is None" and "x is not None" very often. Or "return True" or >> "return None" or "return 1" and things like that. These all expand into two >> bytecodes, which seems pretty non-optimal (LOAD_CONST + COMPARE_OP or >> LOAD_CONST + RETURN_VALUE). It seems we could get an easy speedup for these >> common cases by adding a peephole optimization and some new opcodes (maybe >> COMPARE_IS_SMALL_CONST and RETURN_SMALL_CONST for these cases). >> >> I'm not proposing to do this yet, as I'd need to benchmark to see how >> much of a gain (if any) it would amount to, but I'm just wondering if >> there's any previous work on this kind of thing. Or, if not, any other >> thoughts before I try it? >> >> Thanks, >> Ben >> >> >> _______________________________________________ >> Python-Dev mailing list >> Python-Dev@python.org >> https://mail.python.org/mailman/listinfo/python-dev >> Unsubscribe: https://mail.python.org/mailman/options/python-dev/victor. >> stinner%40gmail.com >> >>
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com