On Tue, Oct 12, 2021 at 06:34:06AM -0000, Jeremiah Vivian wrote:

> So `ord` is already a really fast function with (last check before 
> this thread was posted) 166 nsec per loop. But I'm wondering... doing 
> `ord(a)` produces this bytecode:
>
> >  2           4 LOAD_NAME                1 (ord)
> >              6 LOAD_NAME                0 (a)
> >              8 CALL_FUNCTION            1
> >             10 POP_TOP
> >             12 LOAD_CONST               1 (None)
> >             14 RETURN_VALUE
>
> But doing `+a` only produces this:
>
> >  2           4 LOAD_NAME                0 (a)
> >              6 UNARY_POSITIVE
> >              8 POP_TOP
> >             10 LOAD_CONST               1 (None)
> >             12 RETURN_VALUE

Don't be fooled though, the UNARY_POSITIVE byte-code has to inspect the 
argument `a` for a `__pos__` method, and if it exists, call it. So there 
is a couple of hidden function calls in there.

But it is true that operators do save the cost of looking up the 
function name.


> So an operator has its own bytecode, doesn't need to `LOAD_*` a 
> function, and doesn't have the impact on performance when converting 
> arguments to the format of the (after `POP()`ing every argument) TOS 
> function and then calling that function. 

If the lookup of a function is having a significant cost to you, perhaps 
because you are calling the function in a really tight loop, there is 
an optimization you can do. Suppose we have an enormous string with a 
billion characters, and we run this:

    a = 0
    for c in enormous_string:
        a += ord(c)

That looks up ord once for every character in the string. But if we move 
the code to a function, and use a local variable, we can reduce those 
lookups to one instead of a billion:

    def func(enormous_string):
        ordinal = ord
        a = 0
        for c in enormous_string:
            a += ordinal(c)
        return a

    a = func(enormous_string)

That may give you a small percentage boost.


> And also, the unary `+` of 
> strings only copies strings, which should be redundant in most cases. 

Are you sure about that?

    >>> s = +"a"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: bad operand type for unary +: 'str'

I don't think it works. What version of Python are you using?


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/25OYUA2ZRFJR6I4XFGPC2JIVBGO5DWQY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to