diff -r b7c0137cccbe Objects/setobject.c --- a/Objects/setobject.c Thu Mar 26 23:50:57 2015 +0100 +++ b/Objects/setobject.c Fri Mar 27 09:29:40 2015 +0200 @@ -551,13 +551,14 @@ set_merge(PySetObject *so, PyObject *oth Py_hash_t hash; Py_ssize_t i; setentry *entry; + int clear, dump; assert (PyAnySet_Check(so)); assert (PyAnySet_Check(otherset)); other = (PySetObject*)otherset; if (other == so || other->used == 0) - /* a.update(a) or a.update({}); nothing to do */ + /* a.update(a) or a.update(set()); nothing to do */ return 0; /* Do one big resize at the start, rather than * incrementally resizing as we insert new keys. Expect @@ -567,6 +568,10 @@ set_merge(PySetObject *so, PyObject *oth if (set_table_resize(so, (so->used + other->used)*2) != 0) return -1; } + /* If the table is clear, we can use faster set_insert_clean(). */ + clear = (so->fill == 0); + /* If no dummies, we can just copy entries at the same indices. */ + dump = (other->fill == other->used && so->mask == other->mask); for (i = 0; i <= other->mask; i++) { entry = &other->table[i]; key = entry->key; @@ -574,9 +579,23 @@ set_merge(PySetObject *so, PyObject *oth if (key != NULL && key != dummy) { Py_INCREF(key); - if (set_insert_key(so, key, hash) == -1) { - Py_DECREF(key); - return -1; + if (clear) { + if (dump) { + entry = &so->table[i]; + assert(entry->key == NULL); + entry->key = key; + entry->hash = hash; + so->used++; + so->fill++; + } + else + set_insert_clean(so, key, hash); + } + else { + if (set_insert_key(so, key, hash) == -1) { + Py_DECREF(key); + return -1; + } } } }