Skip to content

Commit 3652952

Browse files
committed
Use an embedded buffer initially to reduce number of allocations
1 parent 3102a02 commit 3652952

File tree

1 file changed

+25
-29
lines changed

1 file changed

+25
-29
lines changed

mypyc/lib-rt/librt_strings.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include "CPy.h"
77
#include "librt_strings.h"
88

9-
#define START_SIZE 512
10-
119
#define CPY_BOOL_ERROR 2
1210
#define CPY_NONE_ERROR 2
1311
#define CPY_NONE 1
@@ -16,11 +14,15 @@
1614
// BytesWriter
1715
//
1816

17+
// Length of the default buffer embedded directly in a BytesWriter object
18+
#define WRITER_EMBEDDED_BUF_LEN 512
19+
1920
typedef struct {
2021
PyObject_HEAD
2122
char *buf; // Beginning of the buffer
2223
char *ptr; // Current write location in the buffer
2324
char *end; // End of the buffer
25+
char data[WRITER_EMBEDDED_BUF_LEN]; // Default buffer
2426
} BytesWriterObject;
2527

2628
#define _WRITE(data, type, v) \
@@ -36,10 +38,15 @@ _grow_buffer(BytesWriterObject *data, Py_ssize_t n) {
3638
Py_ssize_t index = data->ptr - data->buf;
3739
Py_ssize_t target = index + n;
3840
Py_ssize_t size = data->end - data->buf;
41+
Py_ssize_t old_size = size;
3942
do {
4043
size *= 2;
4144
} while (target >= size);
42-
data->buf = PyMem_Realloc(data->buf, size);
45+
if (old_size == WRITER_EMBEDDED_BUF_LEN) {
46+
data->buf = PyMem_Malloc(size);
47+
} else {
48+
data->buf = PyMem_Realloc(data->buf, size);
49+
}
4350
if (unlikely(data->buf == NULL)) {
4451
PyErr_NoMemory();
4552
return false;
@@ -58,6 +65,13 @@ ensure_bytes_writer_size(BytesWriterObject *data, Py_ssize_t n) {
5865
}
5966
}
6067

68+
static inline void
69+
BytesWriter_init_internal(BytesWriterObject *self) {
70+
self->buf = self->data;
71+
self->ptr = self->data;
72+
self->end = self->data + WRITER_EMBEDDED_BUF_LEN;
73+
}
74+
6175
static PyObject*
6276
BytesWriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6377
{
@@ -68,38 +82,17 @@ BytesWriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6882

6983
BytesWriterObject *self = (BytesWriterObject *)type->tp_alloc(type, 0);
7084
if (self != NULL) {
71-
self->buf = NULL;
72-
self->ptr = NULL;
73-
self->end = NULL;
85+
BytesWriter_init_internal(self);
7486
}
7587
return (PyObject *)self;
7688
}
7789

78-
static int
79-
BytesWriter_init_internal(BytesWriterObject *self) {
80-
Py_ssize_t size = START_SIZE;
81-
self->buf = PyMem_Malloc(size + 1);
82-
if (self->buf == NULL) {
83-
PyErr_NoMemory();
84-
return -1;
85-
}
86-
self->ptr = self->buf;
87-
self->end = self->buf + size;
88-
return 0;
89-
}
90-
9190
static PyObject *
9291
BytesWriter_internal(void) {
9392
BytesWriterObject *self = (BytesWriterObject *)BytesWriterType.tp_alloc(&BytesWriterType, 0);
9493
if (self == NULL)
9594
return NULL;
96-
self->buf = NULL;
97-
self->ptr = NULL;
98-
self->end = NULL;
99-
if (BytesWriter_init_internal(self) == -1) {
100-
Py_DECREF(self);
101-
return NULL;
102-
}
95+
BytesWriter_init_internal(self);
10396
return (PyObject *)self;
10497
}
10598

@@ -116,14 +109,17 @@ BytesWriter_init(BytesWriterObject *self, PyObject *args, PyObject *kwds)
116109
return -1;
117110
}
118111

119-
return BytesWriter_init_internal(self);
112+
BytesWriter_init_internal(self);
113+
return 0;
120114
}
121115

122116
static void
123117
BytesWriter_dealloc(BytesWriterObject *self)
124118
{
125-
PyMem_Free(self->buf);
126-
self->buf = NULL;
119+
if (self->buf != self->data) {
120+
PyMem_Free(self->buf);
121+
self->buf = NULL;
122+
}
127123
Py_TYPE(self)->tp_free((PyObject *)self);
128124
}
129125

0 commit comments

Comments
 (0)