Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 937ca98

Browse files
committed
SF patch #687598, array.append is sloooow
This improves speed by about 5.6% for me.
1 parent 577fb5a commit 937ca98

1 file changed

Lines changed: 47 additions & 2 deletions

File tree

Modules/arraymodule.c

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,52 @@
1313
#endif /* DONT_HAVE_SYS_TYPES_H */
1414
#endif /* !STDC_HEADERS */
1515

16+
/* Shamelessy stolen from listobject.c */
17+
static int
18+
roundupsize(int n)
19+
{
20+
unsigned int nbits = 0;
21+
unsigned int n2 = (unsigned int)n >> 5;
22+
23+
/* Round up:
24+
* If n < 256, to a multiple of 8.
25+
* If n < 2048, to a multiple of 64.
26+
* If n < 16384, to a multiple of 512.
27+
* If n < 131072, to a multiple of 4096.
28+
* If n < 1048576, to a multiple of 32768.
29+
* If n < 8388608, to a multiple of 262144.
30+
* If n < 67108864, to a multiple of 2097152.
31+
* If n < 536870912, to a multiple of 16777216.
32+
* ...
33+
* If n < 2**(5+3*i), to a multiple of 2**(3*i).
34+
*
35+
* This over-allocates proportional to the list size, making room
36+
* for additional growth. The over-allocation is mild, but is
37+
* enough to give linear-time amortized behavior over a long
38+
* sequence of appends() in the presence of a poorly-performing
39+
* system realloc() (which is a reality, e.g., across all flavors
40+
* of Windows, with Win9x behavior being particularly bad -- and
41+
* we've still got address space fragmentation problems on Win9x
42+
* even with this scheme, although it requires much longer lists to
43+
* provoke them than it used to).
44+
*/
45+
do {
46+
n2 >>= 3;
47+
nbits += 3;
48+
} while (n2);
49+
return ((n >> nbits) + 1) << nbits;
50+
}
51+
52+
#define NRESIZE(var, type, nitems) \
53+
do { \
54+
size_t _new_size = roundupsize(nitems); \
55+
if (_new_size <= ((~(size_t)0) / sizeof(type))) \
56+
PyMem_RESIZE(var, type, _new_size); \
57+
else \
58+
var = NULL; \
59+
} while (0)
60+
/* END SHAMELESSLY STOLEN CODE */
61+
1662
struct arrayobject; /* Forward */
1763

1864
/* All possible arraydescr values are defined in the vector "descriptors"
@@ -419,8 +465,7 @@ ins1(arrayobject *self, int where, PyObject *v)
419465
if ((*self->ob_descr->setitem)(self, -1, v) < 0)
420466
return -1;
421467
items = self->ob_item;
422-
PyMem_RESIZE(items, char,
423-
(self->ob_size+1) * self->ob_descr->itemsize);
468+
NRESIZE(items, char, (self->ob_size+1) * self->ob_descr->itemsize);
424469
if (items == NULL) {
425470
PyErr_NoMemory();
426471
return -1;

0 commit comments

Comments
 (0)