Skip to content

gh-160725: Speed up print() by looking up write() once per call - #160727

Open
cmaloney wants to merge 2 commits into
python:mainfrom
cmaloney:print_lookup_once
Open

cmaloney wants to merge 2 commits into
python:mainfrom
cmaloney:print_lookup_once

Conversation

@cmaloney

@cmaloney cmaloney commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor
  • Look up file.write once per print() call, instead of once for each argument, separator and line ending.
  • 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.

write() receives the same calls as before. Benchmarks are in the issue: 1.20x faster geometric mean across 8 cases, 5 faster (1.12x to 1.66x) and 3 not significant.

Developed with the help of AI: Claude Opus 5.5.

@python-cla-bot

python-cla-bot Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

Look up the file's write() method once per print() call, instead of once
for each argument, separator and line ending, and pass the cached ' ' and
'\n' strings for the default sep and end directly, instead of converting
them from C strings with PyFile_WriteString().  write() is called exactly
as before.

print() is up to 1.66x faster in pyperf benchmarks, 1.20x geometric
mean; for example, print('a', 1, 2.5) to a file goes from 996 ns to
687 ns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129ST3GmU89AvSnUNSXu2Yi
@cmaloney

Copy link
Copy Markdown
Contributor Author

(force pushed to fixup author line and make cla bot happy)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129ST3GmU89AvSnUNSXu2Yi
@methane

methane commented Oct 27, 2026

Copy link
Copy Markdown
Member

How about concatenating everything and making a single write() call instead of calling file.write() repeatedly? This would likely improve performance significantly. It would also prevent standard output from getting garbled when multiple threads call print(a, b), since another thread could otherwise call print() between the file.write(a) and file.write(b) calls.

@cmaloney

cmaloney commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor Author

I started with that but then found it didn't produce uniform speedup: Copying strings of various sizes into a PyUnicodeWriter instead of doing the "pending" list that TextIOWrapper does would slowdown for some string sizes. It also very significantly changes behavior if a __str__ implementation causes a fault / SIGSEGV. I then profiled and found the repeated method binding was actually most of the runtime so built this PR.

In the longer term I'm hoping to add what I call a "Coherent" print; everything in one print statement gets write() to the underlying device not interleaved with any other print statement. That is a couple versions away though: need to support list of buffers through a lot more of the stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting review type-feature A feature request or enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants