Skip to content

Commit ecc9835

Browse files
committed
Add overallocation for arrays
1 parent f78158f commit ecc9835

File tree

1 file changed

+16
-10
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array

1 file changed

+16
-10
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ public PArray(Object clazz, Shape instanceShape, String formatStr, BufferFormat
5252
this.formatStr = formatStr;
5353
this.format = format;
5454
this.lenght = 0;
55-
this.buffer = new byte[32];
55+
this.buffer = new byte[0];
5656
}
5757

5858
public PArray(Object clazz, Shape instanceShape, String formatStr, BufferFormat format, int length) throws OverflowException {
5959
super(clazz, instanceShape);
6060
this.formatStr = formatStr;
6161
this.format = format;
6262
this.lenght = length;
63-
this.buffer = new byte[Math.max(32, PythonUtils.multiplyExact(length, format.bytesize))];
63+
this.buffer = new byte[PythonUtils.multiplyExact(length, format.bytesize)];
6464
}
6565

6666
public BufferFormat getFormat() {
@@ -84,12 +84,20 @@ public void setLenght(int lenght) {
8484
this.lenght = lenght;
8585
}
8686

87+
private int computeNewSize(int newLength, int itemsize) throws OverflowException {
88+
// Overallocation using the same formula as CPython
89+
int newSize = ((newLength >> 4) + (lenght < 8 ? 3 : 7) + newLength) * itemsize;
90+
if (newSize / itemsize < newLength) {
91+
throw OverflowException.INSTANCE;
92+
}
93+
return newSize;
94+
}
95+
8796
public void ensureCapacity(int newLength) throws OverflowException {
8897
assert newLength >= 0;
89-
// TODO better estimate
90-
int newSize = PythonUtils.multiplyExact(newLength, format.bytesize);
91-
if (newSize > buffer.length) {
92-
byte[] newBuffer = new byte[newSize];
98+
int itemsize = format.bytesize;
99+
if (buffer.length / itemsize < newLength) {
100+
byte[] newBuffer = new byte[computeNewSize(newLength, itemsize)];
93101
PythonUtils.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
94102
buffer = newBuffer;
95103
}
@@ -104,11 +112,9 @@ public void shift(int from, int by) throws OverflowException {
104112
assert from >= 0 && from <= lenght;
105113
assert by >= 0;
106114
int newLength = PythonUtils.addExact(lenght, by);
107-
// TODO better estimate
108115
int itemsize = format.bytesize;
109-
int newSize = PythonUtils.multiplyExact(newLength, itemsize);
110-
if (newSize > buffer.length) {
111-
byte[] newBuffer = new byte[newSize];
116+
if (buffer.length / itemsize < newLength) {
117+
byte[] newBuffer = new byte[computeNewSize(newLength, itemsize)];
112118
PythonUtils.arraycopy(buffer, 0, newBuffer, 0, from * itemsize);
113119
PythonUtils.arraycopy(buffer, from * itemsize, newBuffer, (from + by) * itemsize, (lenght - from) * itemsize);
114120
buffer = newBuffer;

0 commit comments

Comments
 (0)