Why does dict.get(key) run slower than dict[key]

后端 未结 1 685
长发绾君心
长发绾君心 2020-12-11 02:44

While running a numerical integrator, I noticed a noticeable difference in speed depending on how I extract the value of the field in a dictionary

import num         


        
相关标签:
1条回答
  • 2020-12-11 03:25

    Python has to do more work for dict.get():

    • get is an attribute, so Python has to look this up, and then bind the descriptor found to the dictionary instance.
    • () is a call, so the current frame has to be pushed on the stack, a call has to be made, then the frame has to be popped again from the stack to continue.

    The [...] notation, used with a dict, doesn't require a separate attribute step or frame push and pop.

    You can see the difference when you use the Python bytecode disassembler dis:

    >>> import dis
    >>> dis.dis(compile('d[key]', '', 'eval'))
      1           0 LOAD_NAME                0 (d)
                  3 LOAD_NAME                1 (key)
                  6 BINARY_SUBSCR
                  7 RETURN_VALUE
    >>> dis.dis(compile('d.get(key)', '', 'eval'))
      1           0 LOAD_NAME                0 (d)
                  3 LOAD_ATTR                1 (get)
                  6 LOAD_NAME                2 (key)
                  9 CALL_FUNCTION            1
                 12 RETURN_VALUE
    

    so the d[key] expression only has to execute a BINARY_SUBSCR opcode, while d.get(key) adds a LOAD_ATTR opcode. CALL_FUNCTION is a lot more expensive than BINARY_SUBSCR on a built-in type (custom types with __getitem__ methods still end up doing a function call).

    If the majority of your keys exist in the dictionary, you could use try...except KeyError to handle missing keys:

    try:
        return mydict['name']
    except KeyError:
        return None
    

    Exception handling is cheap if there are no exceptions.

    0 讨论(0)
提交回复
热议问题