relative speed of incremention syntaxes (or "i=i+1" VS "i+=1")

Andreas Löscher andreas.loescher at s2005.tu-chemnitz.de
Sun Aug 21 13:27:38 EDT 2011


> What the precise difference (semantics and speed) is between the 
> BINARY_ADD and INPLACE_ADD opcodes, I dunno. Look in the Python source 
> code or maybe someone knows it from memory :-)
> 
> Irmen
> 
from Python/ceval.c:

1316	        case BINARY_ADD:
1317	            w = POP();
1318	            v = TOP();
1319	            if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
1320	                /* INLINE: int + int */
1321	                register long a, b, i;
1322	                a = PyInt_AS_LONG(v);
1323	                b = PyInt_AS_LONG(w);
1324	                /* cast to avoid undefined behaviour
1325	                   on overflow */
1326	                i = (long)((unsigned long)a + b);
1327	                if ((i^a) < 0 && (i^b) < 0)
1328	                    goto slow_add;
1329	                x = PyInt_FromLong(i);
1330	            }
1331	            else if (PyString_CheckExact(v) &&
1332	                     PyString_CheckExact(w)) {
1333	                x = string_concatenate(v, w, f, next_instr);
1334	                /* string_concatenate consumed the ref to v */
1335	                goto skip_decref_vx;
1336	            }
1337	            else {
1338	              slow_add:
1339	                x = PyNumber_Add(v, w);
1340	            }
1341	            Py_DECREF(v);
1342	          skip_decref_vx:
1343	            Py_DECREF(w);
1344	            SET_TOP(x);
1345	            if (x != NULL) continue;
1346	            break;

1532	        case INPLACE_ADD:
1533	            w = POP();
1534	            v = TOP();
1535	            if (PyInt_CheckExact(v) && PyInt_CheckExact(w)) {
1536	                /* INLINE: int + int */
1537	                register long a, b, i;
1538	                a = PyInt_AS_LONG(v);
1539	                b = PyInt_AS_LONG(w);
1540	                i = a + b;
1541	                if ((i^a) < 0 && (i^b) < 0)
1542	                    goto slow_iadd;
1543	                x = PyInt_FromLong(i);
1544	            }
1545	            else if (PyString_CheckExact(v) &&
1546	                     PyString_CheckExact(w)) {
1547	                x = string_concatenate(v, w, f, next_instr);
1548	                /* string_concatenate consumed the ref to v */
1549	                goto skip_decref_v;
1550	            }
1551	            else {
1552	              slow_iadd:
1553	                x = PyNumber_InPlaceAdd(v, w);
1554	            }
1555	            Py_DECREF(v);
1556	          skip_decref_v:
1557	            Py_DECREF(w);
1558	            SET_TOP(x);
1559	            if (x != NULL) continue;
1560	            break;

As for using Integers, the first case (line 1319 and 1535) are true and
there is no difference in Code. However, Python uses a huge switch-case
construct to execute it's opcodes and INPLACE_ADD cames after
BINARY_ADD, hence the difference in speed. 

To be clear, this is nothing you should consider when writing fast code.
Complexity wise they both are the same. 






More information about the Python-list mailing list