-
-
Notifications
You must be signed in to change notification settings - Fork 156
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
Should we remove the C extension? #433
Comments
@carsonburr has written an optimized version in Rust, and some initial benchmarks show it to be around 2x faster or less than Python, similar to the C. But I'm waiting to hear back about running these more detailed benchmarks to see if it's more consistent than the C. Switching to Rust may be an alternative to C if so, but its implementation is just as complex as the C one because of various optimization tricks it uses. |
Somebody's gotta say it: pure Python is easier to integrate with PyPy, for even bigger speedups. If you really want to adopt Rust, consider ensuring that your crate can bind via |
PyPy already gets a build with only the native implementation. We don't build a platform wheel for it, so it falls back to installing from sdist, which skips compiling the speedups for PyPy. |
Submitted a PR with an optimisation that might help these figures. |
Great catch, that greatly improved the performance of Benchmark
Well good news is the speedups are still a clear improvement now. Bad news is we still have the C code and 20 minute publish workflow. |
While it would make maintenance and releases easier, the speedups have now been sped up and are clearly still useful. The good news is that I have the release automated, so I at least can kick it off and come back rather than monitoring it. I'm still interested in a Rust implementation that has close to the same performance, or perhaps exploring mypyc or cython, if anyone's looking for an interesting exploratory task. |
It turns out that Python 3.12 is way faster at string operations than when MarkupSafe and its speedups were written. After running some benchmarks on short and long strings with and without HTML, between Python 3.8, Python 3.12, with and without speedups, the results show that the speedups only offer a fractional speedup, or are in some cases slower than native. Removing the speedups would make maintenance, release, and install much simpler, at some performance cost mitigated by general Python speedup.
Benchmark script
Benchmark output
I couldn't go back further than 3.8 on my machine, but I vaguely remember the benchmarks being much more significantly in favor of the C extension on even older versions. On the order of 5x rather than 1.25x.
If the speedups had never existed, users today compared to 5 years ago would see a significant speedup from Python improvements alone. The speedups are now only faster when many thousands of characters throughout a long string need to be escaped. For short strings or long strings with only minor escaping needed, the speedups are now slower than the Python implementation. Python continues to make performance improvements, such as adding a JIT compiler in 3.13, which may improve MarkupSafe native performance even more.
I have a feeling that most "real" data falls into either short strings like usernames, or medium strings of mostly non-HTML, like blog comments. In which case the speedups are not actually faster. In many cases of longer data, like blog comments, they're probably being preprocessed with Markdown, in which case they're not being escaped by MarkupSafe anyway.
I vaguely understand how the C extension works, but would have trouble maintaining it if something was needed. It also makes the build and publishing much more complicated, requiring 20+ minutes to build 50+ wheels. While the C extension is fairly straightforward, and it's unlikely there's a memory issue, it does deal directly with the internal bits of Python's unicode representation (which is also why it can't be a single abi3 wheel). Removing it would simplify the code, the build/install, and perhaps the perceived security.
The text was updated successfully, but these errors were encountered: