Need some data science work done, easy. Need a web server done, easy. Need things to be fast and relatively performant done, easy.
Need some data science work done, easy. Need a web server done, easy. Need things to be fast and relatively performant done, easy.
Oh, and performance. Not even close. Go is easily 20x performant in each case we've migrated.
> fast
This is only true if you are relying mainly on compiled extensions to do the performance-critical work. Unassisted raw python is super slow compared to Go or Rust.
If you want to write slow, dynamic, hacky code in Rust you have to write 'unwrap' and 'clone' all over the place, obscuring the logic.
Some people in this thread have made the claim that Rust is okay for quick hacky code to work out a solution to a problem, because you can just pepper your code with unwrap and clone and then factor them out later during optimisation. The point I am making is that even if that approach works[0], it heavily obscures your business logic to have it peppered with memory management details when you're just trying to figure out a basic algorithm to solve a problem.
The approach I much prefer is to Plan to Throw One Away[1]. I'd rather work out the solution to my problem in a slow and dynamic language like Python, and then either rewrite it entirely in C or, if possible, just rewrite some inner loop in C and call it from Python.
[0]: I don't think this approach actually works. You can't take a program that has been designed around copying data absolutely everywhere, all over the place, and make it very efficient. You can make it more efficient than it was originally, but I've never seen it done. You can only really work out the right way to manage memory when you know the algorithm, and you can only know the algorithm once you are done. Refactoring from one memory management strategy to another might be possible in theory but is awful in practice, even in Rust.
In rust there are two forms of memory management, 1. You write rust. 2. You write unsafe rust.
You never really have to refactor to suite a different style. Infact changing allocators is as simple as running "cargo install".
Rust isn't as bad as people make it out to be but you do have to invest some time to learning it.
But as far as throw one away goes... You can write it in rust, and then slightly adjust when you do things like clone so nothing gets thrown away unless you really botched it the first time you wrote it.
For example:
Geeqie is an image viewer/manager. It's a fork of the abandoned GQView and is apparently made in the image of Windows 9x-era ACDSee. It's written in C++ and uses GdkPixbuf.
My first prototype for re-creating Geeqie's collection view in PyQt so I could integrate it into a different kind of image management tool was twice as fast at loading thumbnails.
(Something on the order of 20s vs. 10s for loading somewhere around 7000 thumbnails on a 65W TDP dual-core Athlon from 2011.)
I tried quickly benchmarking GdkPixbuf, QImage, Pillow, and the Rust image crate against each other and found that, if anything, GdkPixbuf is a little faster than PyQt... but whatever Geeqie is doing cuts that performance in half.
(And that's with the Python version clamped to single-threaded image loading because I haven't yet written a smart I/O scheduler to allow parallelism on SSDs while avoiding thrashing rotating drives. Experiments with the QThreadPool-limiting line commented out show a speed-up from 10s to roughly 7s, consistent with how much of the overall system CPU capacity was taken up with other things like Firefox at the time.)
I'd also argue that python and performance is totally untrue. Python is probably only second to bitcoin mining in terms of wasted CPU time and global CO2 emissions. Every python programmer that switches to go or rust is the equivalent of removing 15 cars off of the road after all.
Also, Python is super slow comparatively and is only fast if it delegates to other languages.
Not pooping on python it's... Fine. But I am not of the opinion that it's a great choice for all projects because technically "it can" do "anything".
The Rust ecosystem has a broad collection of tooling for using Rust to extend other languages, so there's minimal chance something I wrote in Rust will have to be rewritten to use it in a project in another language.
See https://www.hobofan.com/rust-interop/ and https://areweextendingyet.github.io/
In Python's case, there's also maturin, which aims to make building and publishing Rust-based wheels as easy as Cargo makes doing so for Rust-based crates.
...plus, in the worst case, Rust CLI tools start very quickly, so forking a Rust process for poor man's FFI is more viable, and Serde plus a JSON Schema generator like schemars will streamline microservice-based options.
Jobs to be done and the fastest/cheapest way to get there!