1
Shura 2016-05-08 14:33:45 +08:00 via Android
写着方便啊,而且如果要改变量名,只要改一次
|
2
techme 2016-05-08 14:40:08 +08:00
少打一个字符
|
3
a302800411 2016-05-08 14:45:02 +08:00 via Android
@Shura 用 ide 的重构变量名应该是最准确的,直接替换有时候会出错
|
4
a302800411 2016-05-08 14:45:39 +08:00 via Android
可能是编译器会有特殊处理吧
|
5
hxtheone 2016-05-08 14:46:17 +08:00
会不会是前者计算出右值后会存入一个临时变量然后赋给左侧的 i, 而后者是在 i 本身上做计算, 所以效率会有一点点提升?
个人猜测, 不对请轻喷 |
6
chunqiuyiyu 2016-05-08 14:46:33 +08:00
少打一个字 提升效率 节约生命
|
7
kalintw 2016-05-08 14:47:28 +08:00
可以显示出 PyCharm 的存在感。哈哈。
|
8
crab 2016-05-08 14:51:43 +08:00
一样吧。和大括号另外一行
|
9
junnplus 2016-05-08 14:53:42 +08:00 2
|
10
jsonline 2016-05-08 14:55:00 +08:00
你为什么要发帖
|
11
junnplus 2016-05-08 14:59:36 +08:00 4
In [4]: dis.dis('i = 0; i += 1')
....0 LOAD_CONST.... 0 (0) ....3 STORE_NAME....0 (i) ....6 LOAD_NAME....0 (i) ....9 LOAD_CONST....1 (1) ....12 INPLACE_ADD ....13 STORE_NAME....0 (i) ....16 LOAD_CONST....2 (None) ....19 RETURN_VALUE In [5]: dis.dis('i = 0; i = i + 1') ....0 LOAD_CONST....0 (0) ....3 STORE_NAME....0 (i) ....6 LOAD_NAME....0 (i) ....9 LOAD_CONST....1 (1) ....12 BINARY_ADD ....13 STORE_NAME....0 (i) ....16 LOAD_CONST....2 (None) ....19 RETURN_VALUE 可以看出来,两者的区别只在 INPLACE_ADD 和 BINARY_ADD 上面 |
12
terence4444 OP @junnplus 这是 stackoverflow 的站内搜索?搜索引擎对符号搜索视而不见……
|
13
liuhaotian 2016-05-08 15:09:34 +08:00 via iPhone
只有 i++才有效率的提高因为可以直接 INC X
|
14
junnplus 2016-05-08 15:16:18 +08:00
@terence4444 并不会视而不见呀,你的搜索姿势不对而已
|
15
icybee 2016-05-08 15:18:02 +08:00
个人习惯吧, python 优化完都一样
|
16
loveuqian 2016-05-08 15:19:33 +08:00
@liuhaotian
可是 i++是异步的啊 |
17
elarity 2016-05-08 15:20:57 +08:00
编译器喜欢,就这么简单。
|
18
fy 2016-05-08 15:27:18 +08:00 2
首先是看看字节码,好像区别不大
>>> import dis >>> dis.dis('a += 1') 1 0 LOAD_NAME 0 (a) 3 LOAD_CONST 0 (1) 6 INPLACE_ADD 7 STORE_NAME 0 (a) 10 LOAD_CONST 1 (None) 13 RETURN_VALUE >>> >>> dis.dis('a = a + 1') 1 0 LOAD_NAME 0 (a) 3 LOAD_CONST 0 (1) 6 BINARY_ADD 7 STORE_NAME 0 (a) 10 LOAD_CONST 1 (None) 13 RETURN_VALUE >>> 然后去看字节码解析,貌似一毛一样 ceval.c TARGET(BINARY_ADD) { PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { sum = unicode_concatenate(left, right, f, next_instr); /* unicode_concatenate consumed the ref to v */ } else { sum = PyNumber_Add(left, right); Py_DECREF(left); } Py_DECREF(right); SET_TOP(sum); if (sum == NULL) goto error; DISPATCH(); } TARGET(INPLACE_ADD) { PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { sum = unicode_concatenate(left, right, f, next_instr); /* unicode_concatenate consumed the ref to v */ } else { sum = PyNumber_InPlaceAdd(left, right); Py_DECREF(left); } Py_DECREF(right); SET_TOP(sum); if (sum == NULL) goto error; DISPATCH(); } 然后观察实现: abstract.c PyObject * PyNumber_Add(PyObject *v, PyObject *w) { PyObject *result = binary_op1(v, w, NB_SLOT(nb_add)); if (result == Py_NotImplemented) { PySequenceMethods *m = v->ob_type->tp_as_sequence; Py_DECREF(result); if (m && m->sq_concat) { return (*m->sq_concat)(v, w); } result = binop_type_error(v, w, "+"); } return result; } PyObject * PyNumber_InPlaceAdd(PyObject *v, PyObject *w) { PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add), NB_SLOT(nb_add)); if (result == Py_NotImplemented) { PySequenceMethods *m = v->ob_type->tp_as_sequence; Py_DECREF(result); if (m != NULL) { binaryfunc f = NULL; f = m->sq_inplace_concat; if (f == NULL) f = m->sq_concat; if (f != NULL) return (*f)(v, w); } result = binop_type_error(v, w, "+="); } return result; } 于是我思考之后得出了结论: 他们有什么不同呢?最终调用的槽不同。 但是 python 代码来测试的结果,确实是 += 比 = + 快一点 |
19
fy 2016-05-08 15:28:30 +08:00
另外 Python 的 int 和 str 一样是不可变对象,根本不会有 inc x 这样的东西
|
20
tvallday 2016-05-08 15:28:31 +08:00
参考
https://en.wikipedia.org/wiki/Augmented_assignment 因为编译器并不一定知道 i 是一个普通变量,也有可能是数组里面的元素或者其他复杂类型,这样第一种写法需要找两次 i 。 |
21
est 2016-05-08 15:36:26 +08:00
+= 是个原子操作。 但是 py 估计然并卵。
|
22
qqmishi 2016-05-08 15:39:35 +08:00 via Android 1
+和=是同一个键打起来快,,,
|
23
xuboying 2016-05-08 15:44:56 +08:00 via Android 1
语言搞这种细节就没意思了
|
24
soland 2016-05-08 15:57:00 +08:00
编译有可能不一样。
|
25
RitzoneX 2016-05-08 16:26:33 +08:00
试下 i++
|
26
latyas 2016-05-08 17:17:44 +08:00
|
27
latyas 2016-05-08 17:20:56 +08:00
所以标题应该问:这两个写法有什么区别 会更好一些
|
28
MntCw 2016-05-08 18:00:20 +08:00 via Android
存储器读一次和读两次的区别
|
29
abscon 2016-05-08 18:57:10 +08:00 via iPhone
Python 不是鼓吹只有一种方法做事情么,禁止掉一个吧
|
30
Finalcheat 2016-05-08 20:18:45 +08:00
习惯问题吧,没有任何好处。
|
31
jacy 2016-05-08 20:22:01 +08:00
后者有 B 格
|
32
digimoon 2016-05-08 20:26:34 +08:00
后者我一眼看过去没反应过来是什么东西,可能似乎大概有 B 格
|
33
mhoudg 2016-05-08 20:33:01 +08:00 2
这个步骤的真实意图通常并非做一个加法运算,而是进行自增
i += 1 的写法非常符合 “ i 自增 1 ”这个语言顺序,给人感觉很直观; 而 i = i + 1 的写法会让人第一感受是一个赋值,第二感受是一个假发,相对 += 来说不那么直观 我知道肯定有人会说第二种写法也很直观,而且我不打算讨论什么叫“直观”这个问题 |
34
Patiencec 2016-05-08 20:35:13 +08:00 via iPhone
哈哈,打字习惯
|
35
chrishine 2016-05-08 20:49:37 +08:00
语法糖层面,如果 i 这个变量名很长,优势就出来了。比如你要给某个结构体的某个字段增加某个值。
性能方面,我觉得编译器应该可以优化掉这种 case. |
36
zhuangzhuang1988 2016-05-08 21:36:49 +08:00
@chrishine 标准 python 解释器 是不会优化的
|
37
Joway 2016-05-08 22:11:28 +08:00
以前忘了听谁说的说前者是一个操作,后者是两个,还有那个 ++i 和 i++ 前缀加比后缀加要快。。。然而我觉得这玩意在编译器阶段就已经被优化了,没什么区别。。
|
38
Exin 2016-05-08 22:51:06 +08:00
可以给自己续一秒
|
39
abcdabcd987 2016-05-08 23:10:47 +08:00
刚写完一个编译器,看到这个问题简直泪流满面。比如下面这个句子:
a[i][j][k] = a[i][j][k] + 1 和 a[i][j][k] += 1 两句话翻译出来指令数差了好多啊 T_T |
40
glennq 2016-05-09 00:31:36 +08:00
前者等价于 i = i.__add__(1),后者等价于 i.__iadd__(1),对于 int 这种不可变对象是没太大区别,但在可变对象的情况下不仅效率可能有较大差别,实际产生的效果也不一样。
|
41
atpking 2016-05-09 01:08:06 +08:00
编译器会帮你优化这些的 现在的编译器已经不是石器时代了
|
42
Ginson 2016-05-09 08:59:30 +08:00
作为一个 0 基础新手,我还是觉得 i = i + 1 更直观些
i + = 好在哪里?无所谓了,反正结果一样。 |
43
iiduce 2016-05-09 09:15:17 +08:00
当你找到自认为对的理由后,会有一种优越感。
|
44
iverson68214 2016-05-09 09:15:37 +08:00
變量名長時,差別就出來了
error_count = error_count + 1 error_count += 1 |
45
firemiles 2016-05-09 10:04:18 +08:00
python 用多了连这种举手之劳就可以写成 i += 1 的优化也不愿意做了吗,什么都指望编译器能优化不太好吧。
|
46
knightdf 2016-05-09 10:33:00 +08:00
@iverson68214 确实,第一种丑
|
47
sweelia 2016-05-09 10:56:03 +08:00
i = i++ [再见]
|
49
Joway 2016-05-09 16:11:04 +08:00 via Android
@winoros 我知道你说的,但是实际上我觉得编译器已经能够优化这点了,毕竟那么多人循环都写 i++ (逃
|
50
Override 2016-08-28 22:26:40 +08:00
更加"dry"
你写成 i = i + 1 的话,你要修改 i 这个变量,变成 n = n + 1 ,需要修改两个地方, 而写成 i += 1 ,你只需要修改一个地方就可以变成 n += 1 |