> 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. 



-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to