Reputation: 175
Supposing I need to call one of these functions millions of times, what are the differences in performance between these two ?
typedef struct s_tuple{
double x;
double y;
double z;
double w;
double m;
double n;
double o;
double p;
} t_tuple;
// (1)
t_tuple tuple_mul1(const double q, t_tuple a)
{
a.x *= q;
a.y *= q;
a.z *= q;
a.w *= q;
a.m *= q;
a.n *= q;
a.o *= q;
a.p *= q;
return a;
}
// (2)
t_tuple tuple_mul2(const double q, const t_tuple a)
{
t_tuple b;
b.x = a.x * q;
b.y = a.y * q;
b.z = a.z * q;
b.w = a.w * q;
b.m = a.m * q;
b.n = a.n * q;
b.o = a.o * q;
b.p = a.p * q;
return b;
}
My thoughts at first:
resource-management:
(2) needs to allocate memory on the stack for b, so in terms of resources 2 requires 64 more bytes than (1) per exec
runtime:
(1) does not allocate memory on the stack so it gains the 'stack-allocating a t_tuple' time compared to (2).
BUT !
I made some tests and I am completely off. Actually, 2 runs faster than 1: for 200 millions calls, (2) execs in ~1s, whereas (1) execs in ~1.55s
Edit: I compiled with cc with no options
Can someone please explain why ?
Here is my runtime-test program:
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct s_tuple{
double x;
double y;
double z;
double w;
double m;
double n;
double o;
double p;
} t_tuple;
// (1)
t_tuple tuple_mul1(const double q, t_tuple a)
{
a.x *= q;
a.y *= q;
a.z *= q;
a.w *= q;
a.m *= q;
a.n *= q;
a.o *= q;
a.p *= q;
return a;
}
// (2)
t_tuple tuple_mul2(const double q, const t_tuple a)
{
t_tuple b;
b.x = a.x * q;
b.y = a.y * q;
b.z = a.z * q;
b.w = a.w * q;
b.m = a.m * q;
b.n = a.n * q;
b.o = a.o * q;
b.p = a.p * q;
return b;
}
int main(int ac, char **av)
{
int i;
long int n;
double q;
t_tuple a;
clock_t start, end;
q = 0.7;
a.x = 1.5;
a.y = 2;
a.z = 35897.78;
a.w = 4.6698;
a.m = 5.5;
a.n = 1065;
a.o = 11.6887;
a.p = 109090808.789;
if (ac > 1)
{
n = atol(av[1]);
double execution_time;
start = clock();
for (i = 0; i < n; i++)
tuple_mul1(q, a);
// tuple_mul2(q, a);
end = clock();
execution_time = ((double)(end - start))/CLOCKS_PER_SEC;
printf("exec_time = %f\nn = %.f * 1e6\n", execution_time, n / 1e6);
}
}
Upvotes: 0
Views: 86
Reputation: 11321
What compiler did you use and with what options?
gcc
with -O3
produced identical assembly for both functions: https://godbolt.org/z/YhTW3zzWq
Upvotes: 1