
On Mar 12, 2020, at 14:32, Marco Sulla via Python-ideas <python-ideas@python.org> wrote:
On Thu, 12 Mar 2020 at 21:22, Chris Angelico <rosuav@gmail.com> wrote:
They actually ARE already discarded
0____O You're right. So *how* can juliantaylor said he measured a speedup of 2x for large ndarrays?
Because Julian’s patch has nothing to do with discarding the temporary references. It has to do with knowing that an array is safe to reuse. Having a refcount of 1 is not sufficient to know that for arbitrary Python objects; it is apparently sufficient for numpy arrays if you can prove that there’s nothing but Python code and numpy C code on the stack that might have touched them. So Julian wrote a patch that can check that by walking the C stack. (In fact, I’m not sure even that much is really true. If you use ctypes.pythonapi to call the PyNumber functions from Python, can you trick numpy into incorrectly reusing an array? But I’m guessing they thought about that and decided that’s worth breaking; people who screw with objects at the C level from Python had better know exactly what they’re doing or they get what’s coming to them.)
He added also benchmarks, that are still in numpy code. Furthermore he stated that what he done it's done by Python also for strings.
Yes, but only for strings. Because they are immutable (once shared with the interpreter) and have no reference-borrowing APIs, strings with 1 refcount are safe to reuse, so CPython can try to expand them in-place instead of creating a new string, and everything works. That isn’t true for arbitrary Python objects, only for strings (and a small number of other builtin types that presumably aren’t worth optimizing in this way). As I said before, this is not too different from the fact that the compiler may merge two equal string constants into a single object, and the interpreter may intern strings at runtime, and similar things happen for other known safe immutable types like int, but none of this works for arbitrary Python objects. `"spam" is "spam"` won’t break anything, so the compiler can make that true, but it had better not make `[1] is [1]` true, right? So pointing out that strings have a particular optimization does not argue that all objects should have this optimization.