Hello,
I noticed during benchmarks that calling a function was way faster (x20 difference) compared to calling a method doing the exact same thing, in my case a Vector-Matrix multiplication.
What is the reason for this difference, and what can I do to get the method call to be as fast as the function call?
Here is the code for the function
Function Implementation
fn call_function(
weights: &[[i16; EMBD_SIZE]; LAYER_SIZE],
input: &[i16; EMBD_SIZE],
output: &mut [i16; LAYER_SIZE]) {
for i in 0..LAYER_SIZE {
for j in 0..EMBD_SIZE {
output[i] += input[j] * weights[i][j]
}
}
}
And here is the same thing but using a struct
,
Method Implementation
pub struct LinearTransform {
weights: [[i16; EMBD_SIZE]; LAYER_SIZE],
pub output: [i16; LAYER_SIZE],
}
impl LinearTransform {
pub fn new() -> Self {
Self {
weights: [[0; EMBD_SIZE]; LAYER_SIZE],
output: [0; LAYER_SIZE],
}
}
pub fn forward(&mut self, input: &[i16; EMBD_SIZE]) {
for i in 0..LAYER_SIZE {
for j in 0..EMBD_SIZE {
self.output[i] += input[j] * self.weights[i][j]
}
}
}
}
The timing for 1 million iterations, with a 512 x (512, 32) Matrix product is:
Method time: 6.903119005s
Function time: 315.652135ms
Code for timing:
Timing
use std::time::Instant;
fn main() {
let mut transform = LinearTransform::new();
let input = [0; EMBD_SIZE];
let mut result = 0;
let start = Instant::now();
let mut k = 0;
while k < 1_000_000 {
transform.forward(&input);
result += transform.output[0];
k += 1;
}
println!("{}", result);
let duration = start.elapsed();
println!("Method time: {:?}", duration);
let x = [0; EMBD_SIZE];
let w = [[0; EMBD_SIZE]; LAYER_SIZE];
let mut y = [0; LAYER_SIZE];
let start = Instant::now();
let mut k = 0;
while k < 1_000_000 {
call_function(&w, &x, &mut y);
k += 1;
}
println!("{}", y[0]);
let duration = start.elapsed();
println!("Function time: {:?}", duration);
}
Thanks !