在思考代码的优化时,我想知道在 python 中哪个更昂贵:
if x:
d = 1
else:
d = 2
或者
d = 2
if x:
d = 1
有什么想法吗?我喜欢第二个中减少的行数,但想知道重新分配是否比条件切换更昂贵。
在思考代码的优化时,我想知道在 python 中哪个更昂贵:
if x:
d = 1
else:
d = 2
或者
d = 2
if x:
d = 1
有什么想法吗?我喜欢第二个中减少的行数,但想知道重新分配是否比条件切换更昂贵。
不要思考,不要怀疑,测量——timeit
在 shell 命令行中使用(迄今为止最好、最简单的使用方法!)。笔记本电脑上 Mac OSX 10.5 上的 Python 2.5.4...:
$ python -mtimeit -s'x=0' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0748 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0685 usec per loop
$ python -mtimeit -s'x=0' 'd=2' 'if x: d=1'
10000000 loops, best of 3: 0.0734 usec per loop
$ python -mtimeit -s'x=1' 'd=2' 'if x: d=1'
10000000 loops, best of 3: 0.101 usec per loop
所以你看:与“if/else”形式相比,当 x 为假时,“just-if”形式可以节省 1.4 纳秒,但当 x 为真时需要 40.2 纳秒;因此,在微优化上下文中,只有当 x 是假的可能性比真的可能性高 30 倍时,才应该使用前者,或者大约。还:
$ python -mtimeit -s'x=0' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0736 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.076 usec per loop
... if/else 的三元运算符有其自己的小优点和缺点。
当差异如此微小时,您应该反复测量,确定噪音水平,并确保您没有将“噪音”中的差异视为显着。例如,要在“x 为真”的情况下比较语句与表达式 if/else,请重复几次:
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.076 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0749 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0742 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0749 usec per loop
$ python -mtimeit -s'x=1' 'd=1 if x else 2'
10000000 loops, best of 3: 0.0745 usec per loop
现在您可以声明表达式形式(在这台机器和关键软件的版本上)需要 74.2 到 76.0 纳秒——这个范围比任何单个数字都更具表现力。同样:
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0688 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0681 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0687 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0679 usec per loop
$ python -mtimeit -s'x=1' 'if x: d=1' 'else: d=2'
10000000 loops, best of 3: 0.0692 usec per loop
现在您可以自信地声明语句形式(在相同条件下)需要 67.9 到 69.2 纳秒;所以它的优势,对于 x true,wrt 表达式形式,是 4.8 到 8.1 纳秒(将后一个间隔估计限制为 6.3 到 6.8 纳秒是相当公平的,比较 min/min 和 max/max 而不是 min/max 和 max/ min 作为更广泛、更审慎的估计)。
一旦你意识到它们是微观的,那么有多少时间和精力值得花在这些微观差异上,当然,这是一个不同的问题。
您可能应该对此进行基准测试,但还有第三种形式使用三元运算符:
d = 1 if x else 2
第二个显然应该更昂贵,如果x
为假,它执行相同的操作,如果为真,则执行两次分配x
。
假设:在 python 中赋值比条件跳转更昂贵,这是有道理的,因为它被解释并且它必须读取运行时哈希来获取新值,然后将其上传到相同的哈希中。
我会争辩说,最易读的那个是最优化的(至少在可读性方面)。
if...else 结构清楚地表明您正在处理一个非此即彼的情况。
如果 (d==2) 是通常的值并且您的 if 测试异常情况,则分配结构可能更有意义。如果你的分配远离 if,这个结构就变得不那么清楚了。
在这个简单的例子中,它并不重要。对于更复杂的代码,我几乎总是会优化可读性,即使是以几个 CPU 周期为代价。