Skip to content

Commit 1955eb3

Browse files
cmaloneyclaude
andauthored
gh-160725: Speed up print() by using string constants and doing faster binding (#160727)
Pass the cached ' ' and '\n' strings for the default sep and end directly, instead of converting them from C strings with PyFile_WriteString(), which runs strlen() and the UTF-8 decoder on every call to get back the same cached string. Rebinding file.write during print() keeps working as before. GH-160803 significantly lowered binding cost. Could save ~5ns/call on x64 linux by binding only once, but that is left for work in https://discuss.python.org/t/make-print-use-a-single-write-call/109886 | Benchmark | main | this PR | |------------------------------------------------|:-------:|:---------------------:| | print(file=devnull) | 51.2 ns | 47.4 ns: 1.08x faster | | print('hello world', file=devnull) | 81.0 ns | 79.2 ns: 1.02x faster | | print('a', 1, 2.5, file=devnull) | 281 ns | 278 ns: 1.01x faster | | print('a', 'b', sep='-', end='', file=devnull) | 124 ns | 126 ns: 1.02x slower | Benchmark hidden because not significant (1): print(*ten_ints, file=devnull) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f767423 commit 1955eb3

1 file changed

Lines changed: 8 additions & 24 deletions

File tree

‎Python/bltinmodule.c‎

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,7 +2240,7 @@ builtin_print_impl(PyObject *module, PyObject * const *objects,
22402240
PyObject *file, int flush)
22412241
/*[clinic end generated code: output=38d8def56c837bcc input=ff35cb3d59ee8115]*/
22422242
{
2243-
int i, err;
2243+
int i;
22442244

22452245
if (file == Py_None) {
22462246
file = PySys_GetAttr(&_Py_ID(stdout));
@@ -2259,7 +2259,7 @@ builtin_print_impl(PyObject *module, PyObject * const *objects,
22592259
}
22602260

22612261
if (sep == Py_None) {
2262-
sep = NULL;
2262+
sep = _Py_LATIN1_CHR(' ');
22632263
}
22642264
else if (sep && !PyUnicode_Check(sep)) {
22652265
PyErr_Format(PyExc_TypeError,
@@ -2269,7 +2269,7 @@ builtin_print_impl(PyObject *module, PyObject * const *objects,
22692269
return NULL;
22702270
}
22712271
if (end == Py_None) {
2272-
end = NULL;
2272+
end = _Py_LATIN1_CHR('\n');
22732273
}
22742274
else if (end && !PyUnicode_Check(end)) {
22752275
PyErr_Format(PyExc_TypeError,
@@ -2280,32 +2280,16 @@ builtin_print_impl(PyObject *module, PyObject * const *objects,
22802280
}
22812281

22822282
for (i = 0; i < objects_length; i++) {
2283-
if (i > 0) {
2284-
if (sep == NULL) {
2285-
err = PyFile_WriteString(" ", file);
2286-
}
2287-
else {
2288-
err = PyFile_WriteObject(sep, file, Py_PRINT_RAW);
2289-
}
2290-
if (err) {
2291-
Py_DECREF(file);
2292-
return NULL;
2293-
}
2283+
if (i > 0 && PyFile_WriteObject(sep, file, Py_PRINT_RAW) < 0) {
2284+
Py_DECREF(file);
2285+
return NULL;
22942286
}
2295-
err = PyFile_WriteObject(objects[i], file, Py_PRINT_RAW);
2296-
if (err) {
2287+
if (PyFile_WriteObject(objects[i], file, Py_PRINT_RAW) < 0) {
22972288
Py_DECREF(file);
22982289
return NULL;
22992290
}
23002291
}
2301-
2302-
if (end == NULL) {
2303-
err = PyFile_WriteString("\n", file);
2304-
}
2305-
else {
2306-
err = PyFile_WriteObject(end, file, Py_PRINT_RAW);
2307-
}
2308-
if (err) {
2292+
if (PyFile_WriteObject(end, file, Py_PRINT_RAW) < 0) {
23092293
Py_DECREF(file);
23102294
return NULL;
23112295
}

0 commit comments

Comments
 (0)