简体   繁体   English

为什么加法赋值比赋值慢很多?

[英]Why is addition assignment is much slower than assignment?

I'm quite new to improving python efficiency.我对提高 python 效率还很陌生。 So i've made some tests like;所以我做了一些测试,比如;

Example 1:示例 1:

num = 0
num = 2*2
# time: 13.8 ns ± 0.158 ns per loop

Example 2:示例 2:

num = 0
num += 2*2
# time: 23.8 ns ± 0.232 ns per loop

I am wondering why using addition assignment is much slower, is it because it has addition?我想知道为什么使用加法赋值要慢得多,是因为它有加法吗?

It will become clearer if you use the dis module and wrap everything in a function:如果您使用 dis 模块并将所有内容包装在 function 中,它将变得更加清晰:

    import dis
    def change_link():
        num = 0
        num = 2*2
    def add():
        num = 0 
        num += 2*2

    dis.dis(change_link)
    dis.dis(add)

You will see that change_link() function has fewer steps:您会看到 change_link() function 的步骤更少:

0 LOAD_CONST               1 (0)
2 STORE_FAST               0 (num)
4 LOAD_CONST               2 (4)
6 STORE_FAST               0 (num)
8 LOAD_CONST               0 (None)
10 RETURN_VALUE

instead of add() function:而不是 add() function:

0 LOAD_CONST               1 (0)
2 STORE_FAST               0 (num)
4 LOAD_FAST                0 (num)
6 LOAD_CONST               2 (4)
8 INPLACE_ADD
10 STORE_FAST               0 (num)
12 LOAD_CONST               0 (None)
14 RETURN_VALUE

Simply put, there is much easier to change link to value, than correct (ex. add or multiply) the value.简而言之,更改值的链接比更正(例如加或乘)值要容易得多。

is it because it has addition?是因为有加法吗?

Yes, addition assignment requires the value to be read from memory before writing the new value, whereas a simple assignment does not require this reading step and can just write the value, making it faster.是的,附加赋值需要在写入新值之前从 memory 读取值,而简单的赋值不需要这个读取步骤并且可以直接写入值,从而使其更快。

Well, in one case you have 2 operations: 1 multiplication 2*2 (assuming that it is not already done at parse time. I don't really know the internal of the interpreter. It probably is), and 1 assignment num=4 .好吧,在一种情况下你有 2 个操作:1 个乘法2*2 (假设它在解析时还没有完成。我真的不知道解释器的内部。它可能是)和 1 个赋值num=4 .

In the other 3: 1 multiplication 2*2 , 1 addition num+4 , and one assignment num=4在另外 3 个中:1 个乘法2*2 ,1 个加法num+4和一个赋值num=4

Note that the ratio is certainly less than 3/2 in time.请注意,该比率在时间上肯定小于 3/2。 Because anyway, those are probably not the heaviest part of the computation.因为无论如何,这些可能不是计算中最重的部分。 Accessing memory for example takes longer that an addition.例如,访问 memory 需要比加法更长的时间。 Plus, there is the measurement time.另外,还有测量时间。 If you measure如果你测量

for i in range(100000000):
   x=2*2

a good part of what you'll measure is the for loop.您要测量的很大一部分是 for 循环。

So, there is a big common part in timings.因此,计时有很大的共同点。 And only a small part is about the difference between the 2 operations.并且只有一小部分是关于2个操作之间的区别。 The 3/2 (more realisticly 2/1, since I am pretty sure, without knowing anything about it, that python replace 2*2 by 4 at parsing time. Even my own simple pedagogical interpreters do so. That's a basic feature, and python interpreters are generally not basic), so that 3/2 or 2/1 ratio applies only on a fraction of the computation time. 3/2(更实际的是 2/1,因为我很确定,虽然对此一无所知,但 python 在解析时将 2*2 替换为 4。即使是我自己的简单教学解释器也会这样做。这是一个基本功能,并且python 解释器通常不是基本的),因此 3/2 或 2/1 比率仅适用于一小部分计算时间。

But, well, it is quite normal that x+=2*2 is more expansive than x=2*2 , even if only slightly so.但是, x+=2*2x=2*2更广泛是很正常的,即使只是稍微如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM