relative speed of incremention syntaxes (or "i=i+1" VS "i+=1")
Terry Reedy
tjreedy at udel.edu
Sun Aug 21 15:39:53 EDT 2011
On 8/21/2011 1:27 PM, Andreas Löscher wrote:
>> 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.
With 64 bit 3.2.2 on my Win 7 Pentium, the difference was 4% and with
floats (0.0 and 1.0), 6%
--
Terry Jan Reedy
More information about the Python-list
mailing list