Skip to content

gh-133968: Add fast path to PyUnicodeWriter_WriteStr() #133969

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2025

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented May 13, 2025

Don't call PyObject_Str() if the input type is str.

Don't call PyObject_Str() if the input type is str.
@vstinner
Copy link
Member Author

Microbenchmark:

Mean +- std dev: [ref] 70.5 ns +- 1.1 ns -> [change] 58.3 ns +- 3.8 ns: 1.21x faster

from _testcapi import PyUnicodeWriter
import pyperf

range_100 = range(100)

def bench_write_str():
    writer = PyUnicodeWriter(0)
    for _ in range_100:
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")
        writer.write_str("true")

runner = pyperf.Runner()
runner.bench_func('write_str', bench_write_str, inner_loops=1_000)

@vstinner
Copy link
Member Author

JSON benchmark: #133832 (comment)

Benchmark ref change
encode 100 booleans 9.52 us 7.18 us: 1.33x faster
encode 100 integers 13.9 us 11.6 us: 1.20x faster
encode 100 floats 25.1 us 20.6 us: 1.22x faster
encode 100 "ascii" strings 17.3 us 13.2 us: 1.31x faster
encode ascii string len=100 913 ns 902 ns: 1.01x faster
encode escaped string len=128 1.11 us 1.10 us: 1.01x faster
encode Unicode string len=100 1.09 us 1.07 us: 1.02x faster
encode 1000 booleans 59.6 us 38.9 us: 1.53x faster
encode 1000 integers 104 us 82.7 us: 1.26x faster
encode 1000 floats 210 us 166 us: 1.27x faster
encode 1000 "ascii" strings 132 us 93.2 us: 1.42x faster
encode ascii string len=1000 3.48 us 3.49 us: 1.00x slower
encode escaped string len=896 4.12 us 4.11 us: 1.00x faster
encode Unicode string len=1000 4.90 us 4.91 us: 1.00x slower
encode 10000 booleans 553 us 343 us: 1.61x faster
encode 10000 integers 1.00 ms 805 us: 1.25x faster
encode 10000 floats 2.07 ms 1.62 ms: 1.28x faster
encode 10000 "ascii" strings 1.27 ms 868 us: 1.46x faster
encode ascii string len=10000 28.4 us 28.5 us: 1.00x slower
encode escaped string len=9984 38.5 us 38.6 us: 1.00x slower
encode Unicode string len=10000 42.3 us 42.4 us: 1.00x slower
Geometric mean (ref) 1.18x faster

Encoding booleans is now up to 1.61x faster which is quite appealing!

@vstinner vstinner merged commit fe9f6e8 into python:main May 13, 2025
44 checks passed
@vstinner vstinner deleted the write_str branch May 13, 2025 13:31
@miss-islington-app
Copy link

Thanks @vstinner for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request May 13, 2025
…H-133969)

Don't call PyObject_Str() if the input type is str.
(cherry picked from commit fe9f6e8)

Co-authored-by: Victor Stinner <[email protected]>
@bedevere-app
Copy link

bedevere-app bot commented May 13, 2025

GH-133971 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.14 bugs and security fixes label May 13, 2025
@vstinner
Copy link
Member Author

When I wrote PyUnicodeWriter_WriteStr(), I skipped this fast path since PyObject_Str() already has a fast path. But it seems like adding one in PyUnicodeWriter_WriteStr() makes a big difference on microbenchmarks!

vstinner added a commit that referenced this pull request May 13, 2025
) (#133971)

gh-133968: Add fast path to PyUnicodeWriter_WriteStr() (GH-133969)

Don't call PyObject_Str() if the input type is str.
(cherry picked from commit fe9f6e8)

Co-authored-by: Victor Stinner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant