
1 Shura 2016 年 5 月 8 日 via Android 写着方便啊,而且如果要改变量名,只要改一次 |
2 techme 2016 年 5 月 8 日 少打一个字符 |
4 SkyEcho 2016 年 5 月 8 日 via Android 可能是编译器会有特殊处理吧 |
5 hxtheone 2016 年 5 月 8 日 会不会是前者计算出右值后会存入一个临时变量然后赋给左侧的 i, 而后者是在 i 本身上做计算, 所以效率会有一点点提升? 个人猜测, 不对请轻喷 |
6 chunqiuyiyu 2016 年 5 月 8 日 少打一个字 提升效率 节约生命 |
7 kalintw 2016 年 5 月 8 日 可以显示出 PyCharm 的存在感。哈哈。 |
8 crab 2016 年 5 月 8 日 一样吧。和大括号另外一行 |
9 junnplus 2016 年 5 月 8 日 |
10 jsonline 2016 年 5 月 8 日 你为什么要发帖 |
11 junnplus 2016 年 5 月 8 日 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 上面 |
13 liuhaotian 2016 年 5 月 8 日 via iPhone 只有 i++才有效率的提高因为可以直接 INC X |
14 junnplus 2016 年 5 月 8 日 @terence4444 并不会视而不见呀,你的搜索姿势不对而已 |
15 icybee 2016 年 5 月 8 日 个人习惯吧, python 优化完都一样 |
16 loveuqian 2016 年 5 月 8 日 @liuhaotian 可是 i++是异步的啊 |
17 elarity 2016 年 5 月 8 日 编译器喜欢,就这么简单。 |
18 fy 2016 年 5 月 8 日 首先是看看字节码,好像区别不大 >>> 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 年 5 月 8 日 另外 Python 的 int 和 str 一样是不可变对象,根本不会有 inc x 这样的东西 |
20 tvallday 2016 年 5 月 8 日 参考 https://en.wikipedia.org/wiki/Augmented_assignment 因为编译器并不一定知道 i 是一个普通变量,也有可能是数组里面的元素或者其他复杂类型,这样第一种写法需要找两次 i 。 |
21 est 2016 年 5 月 8 日 += 是个原子操作。 但是 py 估计然并卵。 |
22 qqmishi 2016 年 5 月 8 日 via Android +和=是同一个键打起来快,,, |
23 xuboying 2016 年 5 月 8 日 via Android 语言搞这种细节就没意思了 |
24 soland 2016 年 5 月 8 日 编译有可能不一样。 |
25 RitzoneX 2016 年 5 月 8 日 试下 i++ |
26 latyas 2016 年 5 月 8 日 |
27 latyas 2016 年 5 月 8 日 所以标题应该问:这两个写法有什么区别 会更好一些 |
28 MntCw 2016 年 5 月 8 日 via Android 存储器读一次和读两次的区别 |
29 abscon 2016 年 5 月 8 日 via iPhone Python 不是鼓吹只有一种方法做事情么,禁止掉一个吧 |
30 Finalcheat 2016 年 5 月 8 日 习惯问题吧,没有任何好处。 |
31 jacy 2016 年 5 月 8 日 后者有 B 格 |
32 digimoon 2016 年 5 月 8 日 后者我一眼看过去没反应过来是什么东西,可能似乎大概有 B 格 |
33 mhoudg 2016 年 5 月 8 日 这个步骤的真实意图通常并非做一个加法运算,而是进行自增 i += 1 的写法非常符合 “ i 自增 1 ”这个语言顺序,给人感觉很直观; 而 i = i + 1 的写法会让人第一感受是一个赋值,第二感受是一个假发,相对 += 来说不那么直观 我知道肯定有人会说第二种写法也很直观,而且我不打算讨论什么叫“直观”这个问题 |
34 Patiencec 2016 年 5 月 8 日 via iPhone 哈哈,打字习惯 |
35 chrishine 2016 年 5 月 8 日 语法糖层面,如果 i 这个变量名很长,优势就出来了。比如你要给某个结构体的某个字段增加某个值。 性能方面,我觉得编译器应该可以优化掉这种 case. |
36 zhuangzhuang1988 2016 年 5 月 8 日 @chrishine 标准 python 解释器 是不会优化的 |
37 Joway 2016 年 5 月 8 日 以前忘了听谁说的说前者是一个操作,后者是两个,还有那个 ++i 和 i++ 前缀加比后缀加要快。。。然而我觉得这玩意在编译器阶段就已经被优化了,没什么区别。。 |
38 Exin 2016 年 5 月 8 日 可以给自己续一秒 |
39 abcdabcd987 2016 年 5 月 8 日 刚写完一个编译器,看到这个问题简直泪流满面。比如下面这个句子: a[i][j][k] = a[i][j][k] + 1 和 a[i][j][k] += 1 两句话翻译出来指令数差了好多啊 T_T |
40 glennq 2016 年 5 月 9 日 前者等价于 i = i.__add__(1),后者等价于 i.__iadd__(1),对于 int 这种不可变对象是没太大区别,但在可变对象的情况下不仅效率可能有较大差别,实际产生的效果也不一样。 |
41 atpking 2016 年 5 月 9 日 编译器会帮你优化这些的 现在的编译器已经不是石器时代了 |
42 Ginson 2016 年 5 月 9 日 作为一个 0 基础新手,我还是觉得 i = i + 1 更直观些 i + = 好在哪里?无所谓了,反正结果一样。 |
43 iiduce 2016 年 5 月 9 日 当你找到自认为对的理由后,会有一种优越感。 |
44 iverson68214 2016 年 5 月 9 日 量名,差就出了 error_count = error_count + 1 error_count += 1 |
45 firemiles 2016 年 5 月 9 日 python 用多了连这种举手之劳就可以写成 i += 1 的优化也不愿意做了吗,什么都指望编译器能优化不太好吧。 |
46 knightdf 2016 年 5 月 9 日 @iverson68214 确实,第一种丑 |
47 sweelia 2016 年 5 月 9 日 i = i++ [再见] |
50 Override 2016 年 8 月 28 日 更加"dry" 你写成 i = i + 1 的话,你要修改 i 这个变量,变成 n = n + 1 ,需要修改两个地方, 而写成 i += 1 ,你只需要修改一个地方就可以变成 n += 1 |