21 ms·
Show HN: Python can make 3M+ WebSocket keys per second
- Someone 3y agoThe title should be “optimization-demo” (original title) or “Replacing parts of Python programs by C++ can be easy and profitable”. They replace Python code that makes 5 calls into native code by code that makes 1 call that makes those 5 calls, and get a speed up from 869k calls per second to 3.15m calls per second, so a snarky title could even be “Python-to-native calls are slow”. They could even measure it by adding a C++ version of that def magic_accept(key: str) -> str: return 's3pPLMBiTxaQ9kYGzzhZRbK+xOo=' code and benchmarking that.
- mangeld 3y agoDid you take a look at the C++ implementation of the hashing function they did? I didn't see a single call made there. They replaced python code that makes 5 calls into a single call.
- akx 3y agoThat's a copy-pasted variation of this public-domain SHA1 code: http://ftp.funet.fi/pub/crypt/hash/sha/sha1.c http://ftp.funet.fi/pub/crypt/hash/sha/sha1.c surrounded by base64 decoding and encoding for a known-length binary text. By inlining all library code you use, yes indeed, you too can also not make a single call.
- Someone 3y agoI didn’t. I expect that it makes a difference, though for the observation that Python native calls are relatively slow.
- throwaway2037 3y agoThe hardest part of debugging Python is "hitting the wall" when you come to a native library (compiled C code). And Python has achieved a lot of speed-ups from Py2 to Py3 by adding more compiled C code. This is a real blocker for understanding the foundation library. On the other hand, in Java, with a few exceptions around Swing (native painting for GUIs) in Java, almost everything is written in pure Java, so you can debug all the way down if need be. It is a huge help for understanding the foundation library and all of its edge cases (normal for any huge library). Modern Java debuggers, like IntelliJ, are so crazy, they will decompile JARs and allow you to set debug breakpoints and step-into decompiled code. It is mind blowing when trying to debug a library that you don't own the source code (random quant lib, ancient auth lib, etc.).
- PhilipRoman 3y agoAre python debuggers really unable to integrate with something like GDB? I have no problem debugging native calls from Java. During development I've never seen a case where library source was unavailable. Even proprietary components from other companies come with source included.
- ben-schaaf 3y agoGDB on its own does a reasonable job debugging python: https://wiki.python.org/moin/DebuggingWithGdb https://wiki.python.org/moin/DebuggingWithGdb
- uranusjr 3y agoI feel it’s less about instrumentation but more about Python developers understanding C code.
- throwaway2037 3y agoNo, as a "fluent C speaker", the instrumentation part is much harder than understanding the C code.
- elnatro 3y agoDo you think that relying less in C code could be better for Python and it’s community? I mean less focus on being “glue” between C code and more focus con optimizing the interpreter?
- generichuman 3y agoIt is unlikely people would use Python if it didn't rely on C code. If your ML model takes hours when it can take minutes, or takes days when it can take hours, you will move away. You could move away to another language or a faster interpreter but that's a different discussion. > more focus con optimizing the interpreter This is good but there's an upper bound to performance of interpreted languages. Maybe the Python interpreter could be as fast as V8, but it is unlikely to be fast as JVM. People will need to drop down to C / Fortran for whatever compute intensive work they're doing.
- grodes 3y agoPython can make 3M+ WebSocket keys per second C++ 85.1%
- wheelerof4te 3y agoThe irony of Python.
- keithalewis 3y agoIndeed. "I'm a Pythonjack and I'm okay..."
- k__ 3y ago"...by replacing it with its C++..." Nice try!
- jeroenhd 3y agoThis has nothing to do with websockets and much more with doing hashing and Python-to-native calls. It's comparing generating base64(sha1(something)) in Python which I suppose also means "websocket keys". I'm not sure why the author implemented SHA1 and a base64 digest thereof manually rather than including a small library, but perhaps that was part of the challenge. Python can generate a whole lot more keys per second if you enable SIMD, multithreading, or even GPU support. In fact, Ryzen / 11th+ Gen Intel/ARMv8A have dedicated SHA1 instructions that should significantly boost performance here. Together with something like https://github.com/WojciechMula/base64-avx512 https://github.com/WojciechMula/base64-avx512 I bet you could increase the performance an order of magnitude if daw CPU speed were really a concern. I suppose three million keys per second ought to be enough for any websocket server, especially for a relatively simple implementation of the code.
- YChacker100 3y ago[dead]
- phoe-krk 3y ago> Show HN: Python can make 3M+ WebSocket keys per second > This article is about optimizing a tiny bit of Python code by replacing it with its C++ counterpart. So it's C++ rather than Python.
- keithalewis 3y agoBingo.
- sdiepend 3y agoThe article was posted by "cprogrammer1994", that should've been a hint!
- phoe-krk 3y agoThe first "C" stands for "Cython". /s
- cprogrammer1994 3y agoC stands for, well, C :) also, I do not use Cython.
- sovietmudkipz 3y agoIt’s cool that languages support this kind of stuff. So if you’re writing python the employs this technique and you still want to keep the “OS agnostic” characteristic of python does that mean you’d have to compile multiple C++ binaries and check the OS to see which one to run?
- yw3410 3y agoYes, though hopefully it's been packaged up by the distro otherwise you'll end up having dependency problems if you compiled against a wrong libc or something else.
- lukevp 3y agoAlternatively, you could compile the C++ (or rust or zig) to WebAssembly, and a single binary would run anywhere.
- tyingq 3y agoI suspect part of the speedup is avoiding the python included base64 implementation. Third party extensions[1] claim fairly large improvements. [1] https://github.com/mayeut/pybase64 https://github.com/mayeut/pybase64 This particular one also includes b64encode_as_string, which would also reduce some work/copying.
- raverbashing 3y agoOk now try the python version with Pypy and see how it goes
- akx 3y agoWhile the article clearly says this is a toy/example and so on, one of the nice points of the Python version is that it doesn't e.g. - segfault the interpreter if you pass in something that's not a string - read bogus memory if the length of the string is < 24
- joshxyz 3y agothe tragedy though is websocket tls is what will actually slow us down