为什么类型注释会使 Python 代码变慢?

Why do type annotations make Python code slower?

这些是我在 ipython 中的测试结果。

对于int

In [2]: %time for _  in range(1000): exec('a: int = 4')                                                                                                                         
CPU times: user 12.2 ms, sys: 12 µs, total: 12.2 ms
Wall time: 12.2 ms

In [3]: %time for _  in range(1000): exec('a = 4')                                                                                                                              
CPU times: user 9.5 ms, sys: 0 ns, total: 9.5 ms
Wall time: 9.54 ms

对于str

In [4]: %time for _  in range(1000): exec('a: str = "hello"')                                                                                                                   
CPU times: user 13.3 ms, sys: 0 ns, total: 13.3 ms
Wall time: 13.4 ms

In [5]: %time for _  in range(1000): exec('a = "hello"')                                                                                                                        
CPU times: user 10.4 ms, sys: 0 ns, total: 10.4 ms
Wall time: 10.4 ms

还有 list:

In [6]: %time for _  in range(1000): exec('a: list = [1,2, "hello"]')                                                                                                           
CPU times: user 19.1 ms, sys: 0 ns, total: 19.1 ms
Wall time: 21.5 ms

In [7]: %time for _  in range(1000): exec('a = [1,2, "hello"]')                                                                                                                 
CPU times: user 15.8 ms, sys: 0 ns, total: 15.8 ms
Wall time: 15.8 ms

我知道理论上 listint 注释不应该有任何区别,但没有关于它们的功能。但我刚刚测试了这些类型,以确保使用类型提示会使执行速度降低大约 25%。为什么是这样?据我所知,类型提示对执行没有任何作用。只是花更多的时间来解析它们并将它们添加到 __annotations__ 字典中会使执行时间有这么大的差异吗?

您的方法正在测试将 python 代码的原始字符串版本解释为可执行文件的编译时间。如果您改为将 timeit 与函数一起使用,您将看不到明显的区别:

import timeit


def method1():
    for _ in range(1000): a: int = 4


def method2():
    for _ in range(1000): a = 4


print(timeit.timeit(method1, number=200000))
print(timeit.timeit(method2, number=200000))
2.8046581
2.8103205999999994