Skip to content

Commit 19f252a

Browse files
committed
Improve fast path
1 parent 660d962 commit 19f252a

File tree

1 file changed

+50
-44
lines changed

1 file changed

+50
-44
lines changed

Modules/_json.c

Lines changed: 50 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,10 @@ ascii_escape_unichar(Py_UCS4 c, unsigned char *output, Py_ssize_t chars)
149149
}
150150

151151
static Py_ssize_t
152-
ascii_escape_size(PyObject *pystr)
152+
ascii_escape_size(const void *input, int kind, Py_ssize_t input_chars)
153153
{
154154
Py_ssize_t i;
155-
Py_ssize_t input_chars;
156155
Py_ssize_t output_size;
157-
const void *input;
158-
int kind;
159-
160-
input_chars = PyUnicode_GET_LENGTH(pystr);
161-
input = PyUnicode_DATA(pystr);
162-
kind = PyUnicode_KIND(pystr);
163156

164157
/* Compute the output size */
165158
for (i = 0, output_size = 2; i < input_chars; i++) {
@@ -188,19 +181,12 @@ ascii_escape_size(PyObject *pystr)
188181
}
189182

190183
static PyObject *
191-
ascii_escape_unicode_and_size(PyObject *pystr, Py_ssize_t output_size)
184+
ascii_escape_unicode_and_size(const void *input, int kind, Py_ssize_t input_chars, Py_ssize_t output_size)
192185
{
193186
Py_ssize_t i;
194-
Py_ssize_t input_chars;
195187
Py_ssize_t chars;
196188
PyObject *rval;
197-
const void *input;
198189
Py_UCS1 *output;
199-
int kind;
200-
201-
input_chars = PyUnicode_GET_LENGTH(pystr);
202-
input = PyUnicode_DATA(pystr);
203-
kind = PyUnicode_KIND(pystr);
204190

205191
rval = PyUnicode_New(output_size, 127);
206192
if (rval == NULL) {
@@ -229,23 +215,39 @@ static PyObject *
229215
ascii_escape_unicode(PyObject *pystr)
230216
{
231217
/* Take a PyUnicode pystr and return a new ASCII-only escaped PyUnicode */
232-
Py_ssize_t output_size = ascii_escape_size(pystr);
218+
Py_ssize_t input_chars;
219+
const void *input;
220+
int kind;
221+
222+
input_chars = PyUnicode_GET_LENGTH(pystr);
223+
input = PyUnicode_DATA(pystr);
224+
kind = PyUnicode_KIND(pystr);
225+
226+
Py_ssize_t output_size = ascii_escape_size(input, kind, input_chars);
233227
if (output_size < 0) {
234228
return NULL;
235229
}
236230

237-
return ascii_escape_unicode_and_size(pystr, output_size);
231+
return ascii_escape_unicode_and_size(input, kind, input_chars, output_size);
238232
}
239233

240234
static int
241235
write_escaped_ascii(PyUnicodeWriter *writer, PyObject *pystr)
242236
{
243-
Py_ssize_t output_size = ascii_escape_size(pystr);
237+
Py_ssize_t input_chars;
238+
const void *input;
239+
int kind;
240+
241+
input_chars = PyUnicode_GET_LENGTH(pystr);
242+
input = PyUnicode_DATA(pystr);
243+
kind = PyUnicode_KIND(pystr);
244+
245+
Py_ssize_t output_size = ascii_escape_size(input, kind, input_chars);
244246
if (output_size < 0) {
245247
return -1;
246248
}
247249

248-
if (output_size == PyUnicode_GET_LENGTH(pystr) + 2) {
250+
if (output_size == input_chars + 2) {
249251
/* No need to escape anything */
250252
if (PyUnicodeWriter_WriteChar(writer, '"') < 0) {
251253
return -1;
@@ -256,7 +258,7 @@ write_escaped_ascii(PyUnicodeWriter *writer, PyObject *pystr)
256258
return PyUnicodeWriter_WriteChar(writer, '"');
257259
}
258260

259-
PyObject *rval = ascii_escape_unicode_and_size(pystr, output_size);
261+
PyObject *rval = ascii_escape_unicode_and_size(input, kind, input_chars, output_size);
260262
if (rval == NULL) {
261263
return -1;
262264
}
@@ -265,17 +267,10 @@ write_escaped_ascii(PyUnicodeWriter *writer, PyObject *pystr)
265267
}
266268

267269
static Py_ssize_t
268-
escape_size(PyObject *pystr)
270+
escape_size(const void *input, int kind, Py_ssize_t input_chars)
269271
{
270272
Py_ssize_t i;
271-
Py_ssize_t input_chars;
272273
Py_ssize_t output_size;
273-
const void *input;
274-
int kind;
275-
276-
input_chars = PyUnicode_GET_LENGTH(pystr);
277-
input = PyUnicode_DATA(pystr);
278-
kind = PyUnicode_KIND(pystr);
279274

280275
/* Compute the output size */
281276
for (i = 0, output_size = 2; i < input_chars; i++) {
@@ -303,20 +298,11 @@ escape_size(PyObject *pystr)
303298
}
304299

305300
static PyObject *
306-
escape_unicode_and_size(PyObject *pystr, Py_ssize_t output_size)
301+
escape_unicode_and_size(const void *input, int kind, Py_UCS4 maxchar, Py_ssize_t input_chars, Py_ssize_t output_size)
307302
{
308303
Py_ssize_t i;
309-
Py_ssize_t input_chars;
310304
Py_ssize_t chars;
311305
PyObject *rval;
312-
const void *input;
313-
int kind;
314-
Py_UCS4 maxchar;
315-
316-
maxchar = PyUnicode_MAX_CHAR_VALUE(pystr);
317-
input_chars = PyUnicode_GET_LENGTH(pystr);
318-
input = PyUnicode_DATA(pystr);
319-
kind = PyUnicode_KIND(pystr);
320306

321307
rval = PyUnicode_New(output_size, maxchar);
322308
if (rval == NULL)
@@ -376,23 +362,43 @@ static PyObject *
376362
escape_unicode(PyObject *pystr)
377363
{
378364
/* Take a PyUnicode pystr and return a new escaped PyUnicode */
379-
Py_ssize_t output_size = escape_size(pystr);
365+
Py_ssize_t input_chars;
366+
const void *input;
367+
int kind;
368+
Py_UCS4 maxchar;
369+
370+
maxchar = PyUnicode_MAX_CHAR_VALUE(pystr);
371+
input_chars = PyUnicode_GET_LENGTH(pystr);
372+
input = PyUnicode_DATA(pystr);
373+
kind = PyUnicode_KIND(pystr);
374+
375+
Py_ssize_t output_size = escape_size(input, kind, input_chars);
380376
if (output_size < 0) {
381377
return NULL;
382378
}
383379

384-
return escape_unicode_and_size(pystr, output_size);
380+
return escape_unicode_and_size(input, kind, maxchar, input_chars, output_size);
385381
}
386382

387383
static int
388384
write_escaped_unicode(PyUnicodeWriter *writer, PyObject *pystr)
389385
{
390-
Py_ssize_t output_size = escape_size(pystr);
386+
Py_ssize_t input_chars;
387+
const void *input;
388+
int kind;
389+
Py_UCS4 maxchar;
390+
391+
maxchar = PyUnicode_MAX_CHAR_VALUE(pystr);
392+
input_chars = PyUnicode_GET_LENGTH(pystr);
393+
input = PyUnicode_DATA(pystr);
394+
kind = PyUnicode_KIND(pystr);
395+
396+
Py_ssize_t output_size = escape_size(input, kind, input_chars);
391397
if (output_size < 0) {
392398
return -1;
393399
}
394400

395-
if (output_size == PyUnicode_GET_LENGTH(pystr) + 2) {
401+
if (output_size == input_chars + 2) {
396402
/* No need to escape anything */
397403
if (PyUnicodeWriter_WriteChar(writer, '"') < 0) {
398404
return -1;
@@ -403,7 +409,7 @@ write_escaped_unicode(PyUnicodeWriter *writer, PyObject *pystr)
403409
return PyUnicodeWriter_WriteChar(writer, '"');
404410
}
405411

406-
PyObject *rval = escape_unicode_and_size(pystr, output_size);
412+
PyObject *rval = escape_unicode_and_size(input, kind, maxchar, input_chars, output_size);
407413
if (rval == NULL) {
408414
return -1;
409415
}

0 commit comments

Comments
 (0)