]> granicus.if.org Git - python/commitdiff
bpo-29949: Fix set memory usage regression (GH-943)
authorINADA Naoki <methane@users.noreply.github.com>
Sat, 1 Apr 2017 08:20:25 +0000 (17:20 +0900)
committerGitHub <noreply@github.com>
Sat, 1 Apr 2017 08:20:25 +0000 (17:20 +0900)
Revert "Minor factoring:  move redundant resize scaling logic into the resize function."

This reverts commit 4897300276d870f99459c82b937f0ac22450f0b6.

Misc/NEWS
Objects/setobject.c

index b0a0ba02a1e766aa51fefdbb1f1431da80d2e1ed..a9acaf8e62f695b2329331d31cec7d6ca809759b 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ What's New in Python 3.7.0 alpha 1?
 Core and Builtins
 -----------------
 
+- bpo-29949: Fix memory usage regression of set and frozenset object.
+
 - bpo-29935: Fixed error messages in the index() method of tuple, list and deque
   when pass indices of wrong type.
 
index 2ccf183e3c79117c8c25bc5bc1265c5cb4eb675b..23b32d0d83b2e95115122e3f3c3b3cb8481098e6 100644 (file)
@@ -236,7 +236,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
     entry->hash = hash;
     if ((size_t)so->fill*5 < mask*3)
         return 0;
-    return set_table_resize(so, so->used);
+    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
 
   found_active:
     Py_DECREF(key);
@@ -302,7 +302,6 @@ set_table_resize(PySetObject *so, Py_ssize_t minused)
     setentry small_copy[PySet_MINSIZE];
 
     assert(minused >= 0);
-    minused = (minused > 50000) ? minused * 2 : minused * 4;
 
     /* Find the smallest table size > minused. */
     /* XXX speed-up with intrinsics */
@@ -643,8 +642,8 @@ set_merge(PySetObject *so, PyObject *otherset)
      * that there will be no (or few) overlapping keys.
      */
     if ((so->fill + other->used)*5 >= so->mask*3) {
-       if (set_table_resize(so, so->used + other->used) != 0)
-           return -1;
+        if (set_table_resize(so, (so->used + other->used)*2) != 0)
+            return -1;
     }
     so_entry = so->table;
     other_entry = other->table;
@@ -987,7 +986,7 @@ set_update_internal(PySetObject *so, PyObject *other)
         if (dictsize < 0)
             return -1;
         if ((so->fill + dictsize)*5 >= so->mask*3) {
-            if (set_table_resize(so, so->used + dictsize) != 0)
+            if (set_table_resize(so, (so->used + dictsize)*2) != 0)
                 return -1;
         }
         while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
@@ -1507,7 +1506,7 @@ set_difference_update_internal(PySetObject *so, PyObject *other)
     /* If more than 1/4th are dummies, then resize them away. */
     if ((size_t)(so->fill - so->used) <= (size_t)so->mask / 4)
         return 0;
-    return set_table_resize(so, so->used);
+    return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);
 }
 
 static PyObject *