]> git.ipfire.org Git - thirdparty/Python/cpython.git/commit
A (very) slight speed improvement for iterating over bytes (#21705)
authorGuido van Rossum <guido@python.org>
Mon, 3 Aug 2020 16:04:13 +0000 (09:04 -0700)
committerGitHub <noreply@github.com>
Mon, 3 Aug 2020 16:04:13 +0000 (09:04 -0700)
commit488512bf4953d856fcb049a05060a450af52fcdc
tree27a37555ebd95259ca97d726fbd5eb3bed1a8b3c
parentc36dbac588e1d99975f285a874bb20e9f5040af4
A (very) slight speed improvement for iterating over bytes (#21705)

My mentee @xvxvxvxvxv noticed that iterating over array.array is
slightly faster than iterating over bytes.  Looking at the source I
observed that arrayiter_next() calls `getitem(ao, it->index++)` wheras
striter_next() uses the idiom (paraphrased)

    item = PyLong_FromLong(seq->ob_sval[it->it_index]);
    if (item != NULL)
        ++it->it_next;
    return item;

I'm not 100% sure but I think that the second version has fewer
opportunity for the CPU to overlap the `index++` operation with the
rest of the code (which in both cases involves a call).  So here I am
optimistically incrementing the index -- if the PyLong_FromLong() call
fails, this will leave the iterator pointing at the next byte, but
honestly I doubt that anyone would seriously consider resuming use of
the iterator after that kind of failure (it would have to be a
MemoryError).  And the author of arrayiter_next() made the same
consideration (or never ever gave it a thought :-).

With this, a loop like

    for _ in b: pass

is now slightly *faster* than the same thing over an equivalent array,
rather than slightly *slower* (in both cases a few percent).
Objects/bytesobject.c