Hi all. I've been trying to port a Python program at my job and it went well for the most parts except when I tried to code a Rust version of
scipy.ndimage.filters.gaussian_filter doc. In brief, it's doing a convolution between some padded data and a weights vector, for all element of the input array.
Here's my clean version. The problem is that it's super slow! (Yes, I'm calling this function thousands of times) For an input image of dimension [134, 156, 130] and a weights array of length 5, this version takes 180ms to run, while SciPy takes around 23ms.
So I tried several things in the past days... going from a clean version to an unsafe low level version. Here's the fast version (you can call the tests and bench if you clone this project). I actually got faster then SciPy at around 17ms. The slow parts were
ndarrayhigh level tools like
- to much math operations for indexing.
- the bounds check.
The trouble is:
- OMG, it's ugly! Rust has spoiled me and now I'm used to beautiful code
assert!makes everything faster, which seems weird. It's probably because it allows the compiler to avoid some bounds check, but I'm using unsafe r/w so I don't understand why it matters.
- I can't use
unsafeat work. It's forbidden. Of course I could put this in an open source crate and then I'll be able to use it at work but I would argue that there should be no
unsafeeven on an official crate.
Is there a way to remove the
unsafe and stay fast "enough"? We don't really care if we're 5-10% slower than SciPy but 50% slower is too slow! Right now, replacing the r/w with their safe version makes the application around 55% slower. So, do you have any suggestions?