(original) (raw)

On Jun 8, 2016 8:13 AM, "Paul Sokolovsky" <pmiscml@gmail.com> wrote:
\>
\> Hello,
\>
\> On Wed, 8 Jun 2016 14:45:22 +0300
\> Serhiy Storchaka <storchaka@gmail.com> wrote:
\>
\> \[\]
\>
\> > > $ ./run-bench-tests bench/bytealloc\*
\> > > bench/bytealloc:
\> > > 3.333s (+00.00%) bench/bytealloc-1-bytes\_n.py
\> > > 11.244s (+237.35%) bench/bytealloc-2-repeat.py
\> >
\> > If the performance of creating an immutable array of n zero bytes is
\> > important in MicroPython, it is worth to optimize b"\\0" \* n.
\>
\> No matter how you optimize calloc + something, it's always slower than
\> just calloc.

\`bytes(n)\` \*is\* calloc + something. It's a lookup of and call to a global function. (Unless MicroPython optimizes away lookups for builtins, in which case it can theoretically optimize b"\\0".\_\_mul\_\_.)

On the other hand, b"\\0" is a constant, and \* is an operator lookup that succeeds on the first argument (meaning, perhaps, a successful branch prediction). As a constant, it is only created once, so there's no intermediate object created.

AFAICT, the first requires optimizing global function lookups + calls, and the second requires optimizing lookup and \*successful\* application of \_\_mul\_\_ (versus failure + fallback to some \_\_rmul\_\_), and repetitions of a particular \`bytes\` object (which can be interned and checked against). That means there is room for either to win, depending on the efforts of the implementers.

(However, \`bytearray\` has no syntax for literals (and therefore easy constants), and is a more valid and, AFAIK, more practical concern.)