I think a big mistake in the article, in a context where performance is the main objective, is that the author uses an array of structs (AoS), rather than a struct of arrays (SoA). An SoA makes it so that the data is ordered contiguously, which is easy to read for the CPU, while an AoS structure interleaves different data (namely the x and y in this case), which is very annoying for the CPU. A CPU likes to read chunk…
Making Python faster with Rust
171–180 of 223 posts
Re: Making Python faster with Rust
#172Earlier quoted context omitted.
>Today, there is a Python package for everything . The same could be said about CPAN and NPM. Yet Perl is basically dead and JavaScript isn't used for any machine learning tasks as far as I'm aware. WebAssembly did help bring a niche array of audio and video codecs to the ecosystem[1][2], something I'm yet to see from Python. I don't use Python, but with what little exposure I've had to it at work, its overall sluggi…
> WebAssembly did help bring a niche array of audio and video codecs to the ecosystem Python already has all those: the ctypes module is just as hard to use as WebAssembly, with a much lower barrier-to-entry.
Re: Making Python faster with Rust
#173Earlier quoted context omitted.
tbf you don't need to go to C. You could write Common Lisp or Ocaml, both academic high level languages and very performant. Hell SBCL can get you to C range performance wise while you're writing dynamic, GCed code. Sure it's a little bit more involved than learning Python but not that much if you get 50x performance for free. Prevalence of Python is really baffling to me because compute resources cost money.
academic for CS maybe. Not so much for chemistry, biology etc. If you work in computation areas of those subjects you are more likely to know matlab, R, python and maybe Julia. I didn't know of anybody who had done any Lisp or Ocaml in my time in academia (in chemistry, chemical engineering and biology departments), but that's just 3 universities, and i certainly didn't know everybody.
Re: Making Python faster with Rust
#174Earlier quoted context omitted.
Nope. Map() is same speed as for loop. Benchmarking methodology in the link is not good. Author should use timeit() or cProfiler or so. 0.01s of difference is mostly due to fluctuation. The order of execution also matters. Say you want to test A and B function, you need actually to run A, B, B, A to see if the ordering brings the different.
Yeah I guess this isn't true anymore, it looks like maybe it was true in 2.6 days.
list(map(func, arr)) did bring 10% benefits if the func is builtin e.g. int(), str().
But if func is tuple(), list(), set() or any kind of user defined function, list(map()) is always slower.
You can try yourself to see list(map()) is not working well:
import numpy as np
a = np.arrange(100000, 100000)
%%timeit
b1 = [np.sum(x) for x in a]
# repeat once
%%timeit
b2 = list(map(np.sum, a))
# repeat once
import gc
gc.collect()
%%timeit
b2 = list(map(np.sum, a))
# repeat once
b1 = [np.sum(x) for x in a]
# repeat once
I guess that's why I only use map() if and only if is it the case 'list(map(itemgetter, arr))', because generally there is no benefit to use it.Re: Making Python faster with Rust
#175The most important part of the article seems to be that this Python code is taking "an avg of 293.41ms per iteration": def find_close_polygons( polygon_subset: List[Polygon], point: np.array, max_dist: float ) -> List[Polygon]: close_polygons = [] for poly in polygon_subset: if np.linalg.norm(poly.center - point) And after replacing it with this Rust code, it is taking "an avg of 23.44ms per iteration": use pyo3::pre…
I was surprised that the Rust version is _only_ 13x as fast as the Python version.
Re: Making Python faster with Rust
#176Earlier quoted context omitted.
It might have been added later, but the author mentions vectorization in the beginning: > It’s worth noting that converting parts of / everything to vectorized numpy might be possible for this toy library, but will be nearly impossible for the real library while making the code much less readable and modifiable, and the gains are going to be limited (here’s a partially vertorized version, which is faster but far from…
Semi Vectorized code: https://github.com/ohadravid/poly-match/blob/main/poly_match... Expecting Python engineers unable to read defacto standard numpy code but meanwhile expect everyone can read Rust..... Not to mention that the semi-vectorized code is still suboptimal. Too many for loops despite the author clearly know they can all be vectorized. For example instead the author can just write something like: np.argmi…
Re: Making Python faster with Rust
#177I think a big mistake in the article, in a context where performance is the main objective, is that the author uses an array of structs (AoS), rather than a struct of arrays (SoA). An SoA makes it so that the data is ordered contiguously, which is easy to read for the CPU, while an AoS structure interleaves different data (namely the x and y in this case), which is very annoying for the CPU. A CPU likes to read chunk…
Having used this approach in a few languages, I agree that it's (sometimes) (much) better for performance, but it tends to wreak havoc on readability.
Re: Making Python faster with Rust
#178Re: Making Python faster with Rust
#179Earlier quoted context omitted.
Having used this approach in a few languages, I agree that it's (sometimes) (much) better for performance, but it tends to wreak havoc on readability.
Languages and with some sort of decent metaprogramming support can alleviate this sort of issue (see Zig, Julia, Jai, etc.)
Re: Making Python faster with Rust
#180Earlier quoted context omitted.
Semi Vectorized code: https://github.com/ohadravid/poly-match/blob/main/poly_match... Expecting Python engineers unable to read defacto standard numpy code but meanwhile expect everyone can read Rust..... Not to mention that the semi-vectorized code is still suboptimal. Too many for loops despite the author clearly know they can all be vectorized. For example instead the author can just write something like: np.argmi…
Not super familiar with Python but isn't that append call within a loop going to cause a lot of allocations?
Of couse you can prelocate memory for size=3000, and append stuff in a loop. But this saves only 10ms. Too insignificant.