-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
[WIP] gh-129813: Add PyBytesWriter C API #129814
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
Conversation
vstinner
commented
Feb 7, 2025
•
edited by bedevere-app
bot
Loading
edited by bedevere-app
bot
- Replace usage of the old private _PyBytesWriter with the new public PyBytesWriter C API.
- Remove the old private _PyBytesWriter C API.
- Add a freelist for PyBytesWriter_Create().
- TODO: write doc
- TODO: document new functions in What's New and Changelog
- Issue: [C API] PEP 782: Add PyBytesWriter API #129813
* Replace usage of the old private _PyBytesWriter with the new public PyBytesWriter C API. * Remove the old private _PyBytesWriter C API. * Add a freelist for PyBytesWriter_Create(). * TODO: write doc * TODO: document new functions in What's New and Changelog
The PR is big because it also replaces usage of the old private API with new public API. If the API is approved, I will split the PR into smaller pieces and measure the performance impact of these changes. |
Some functions should be optimized after the removal of the private min_size member:
These functions allocate a little bit too much memory, extend argument of PyBytesWriter_Extend() should be adjusted. I just tried to make the code work, not to optimize it. |
This change has no impact on performance, even if the new public API allocates memory on the heap, instead of allocating on the stack. It uses a freelist to optimize Example of microbenchmark on 3 functions: import pyperf
import binascii
runner = pyperf.Runner()
runner.bench_func('from list 100', bytes, list(b'x' * 100))
runner.bench_func('from list 1,000', bytes, list(b'x' * 1_000))
runner.bench_func('from hex 100', bytes.fromhex, bytes(range(100)).hex())
runner.bench_func('from hex 1,000', bytes.fromhex, (b'x' * 1_000).hex())
runner.bench_func('b2a_uu', binascii.b2a_uu, b'x' * 45) Result:
Benchmark hidden because not significant (1): b2a_uu |
pseudo-tangential idea: Could this instead just be a C wrapper for |
|
It seems like most developers are confused by the API which requires to pass writer and buf to most functions. I abandon this API. |