This content originally appeared on DEV Community and was authored by Maximilian
Optimising code for high performance can be exhausting; where can you squeeze that last bit of speed out of your code? How can you be faster than that one piece of code you found online?
For that, let's take a look at the following example of our Rust crate:
pub fn new(values: &Vec<f64>) -> MathVector {
let mut len: f64 = 0;
for i in values {
len += i * i;
}
MathVector { values: values.clone(),
dimension: values.len(),
length: len.sqrt() }
}
Among other things - like the for loop for example - one thing is the problem. Can you spot it? The answer is: len.sqrt()
. Getting the square root of a number is performance-wise extremely expensive - how should we get rid of it? You might guess, that we could implement something like the infamous "Fast inverse square root" algorithm from Quake III. This has one problem though: It's inaccurate. And for something like mathematical applications, this is sometimes very unwanted. So we need to solve this in another way.
I got it: Why don't we calculate it only when the value is actually needed? Let's do it!
But firstly, we need to find a value for this field which cannot be occupied by pure chance. 0 is no candidate, as a vector may have the length 0. But what about a negative length? That sounds good. You are not able to have a negative length of a vector because of the nature of mathematics; the length of a vector is calculated by the sum of the squares of all values, and then taking the square root. As the value of a square root is - by definition - never negative, we can say with confidence that a negative number is ideal. Let's take -1.
Now we need to generate a new getter for the field length
, which only calculates it when actually needed. The code looks like this:
pub fn length(self: &mut Self) -> f64 {
match self.length < 0f64 {
true => { let mut len: f64 = 0f64;
for i in &self.values {
len += i * i;
}
self.length = len;
return self.length;
}
false => { return self.length; }
}
}
As you can clearly see, we check if the length is already set using the logic from our thought; if so, we can just return that. If it is -1 (or some other negative value), we just calculate the length, store it and return the newly calculated length.
And that's it! With just a few more lines of code, we removed unneccessary computations by calculating something only when it is needed. Feel inspired to apply that whereever you can!
This content originally appeared on DEV Community and was authored by Maximilian
Maximilian | Sciencx (2021-12-02T20:45:18+00:00) Optimising Code – The Devil Lies In the Details. Retrieved from https://www.scien.cx/2021/12/02/optimising-code-the-devil-lies-in-the-details/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.