I recently used C in many projects and almost completely created my own "object implementation" with structure pointers. However, I was interested to know about the difference in speed between a purely functional style (with structures) and structures that call pointer functions in a more modern, object-oriented style.
I created a sample program and do not know why the time difference is so great.
The program uses two timers and records the time taken to complete each task (one after the other). This does not include memory allocation / allocation, and both methods are configured in the same way (each structure has three integers as pointers to the structure).
The code itself simply adds three numbers together in the for loop for the time specified in the LOOP_LEN macro .
Please note: I have functions that are measured as inlined , and compiler optimization ranges from none to Full Optimization (/ Ox) (I run this in Visual Studio as a clean .c file).
Object Style Code
typedef struct {
int* x;
int* y;
int* z;
void(*init)(struct magic* self, int x, int y, int z);
int(*sum)(struct magic* self);
}magic;
void* init(magic* self, int x, int y, int z) {
*self->x = x;
*self->y = y;
*self->z = y;
return;
}
inline int sum(magic* self) {
return ((*self->x) + (*self->y) + (*self->z));
}
magic* new_m(int x, int y, int z) {
magic* self = malloc(sizeof(magic));
self->x = malloc(sizeof(int));
self->y = malloc(sizeof(int));
self->z = malloc(sizeof(int));
self->init = init;
self->sum = sum;
return self;
}
void delete_m(magic* self) {
free(self->x); self->x = NULL;
free(self->y); self->y = NULL;
free(self->z); self->z = NULL;
free(self); self = NULL;
return;
}
Functional (traditional) style code
typedef struct {
int* x;
int* y;
int* z;
}str_magic;
str_magic* new_m_str(int x, int y, int z) {
str_magic* self = malloc(sizeof(str_magic));
self->x = malloc(sizeof(int));
self->y = malloc(sizeof(int));
self->z = malloc(sizeof(int));
return self;
}
void delete_m_str(str_magic* self) {
free(self->x); self->x = NULL;
free(self->y); self->y = NULL;
free(self->z); self->z = NULL;
free(self); self = NULL;
return;
}
inline int sum_str(str_magic* self) {
return ((*self->x) + (*self->y) + (*self->z));
}
Timer test and main program entry point
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define LOOP_LEN 1000000000
int main(void) {
clock_t start1, end1, start2, end2;
double cpu_time_used1, cpu_time_used2;
magic* object1 = new_m(1, 2, 3);
start1 = clock();
for (int i = 0; i < LOOP_LEN; i++) {
int result1 = object1->sum(object1);
}
end1 = clock();
delete_m(object1);
cpu_time_used1 = ((double)(end1 - start1)) / CLOCKS_PER_SEC;
str_magic* object2 = new_m_str(1, 2, 3);
start2 = clock();
for (int i = 0; i < LOOP_LEN; i++) {
int result2 = sum_str(object2);
}
end2 = clock();
delete_m_str(object2);
cpu_time_used2 = ((double)(end2 - start2)) / CLOCKS_PER_SEC;
printf("----------------------\n Task 1 : %.*e\n----------------------\n Task 2 : %.*e\n----------------------\n", cpu_time_used1, cpu_time_used2);
if (cpu_time_used1 < cpu_time_used2) {
printf("Object Oriented Approach was faster by %.*e\n", cpu_time_used2-cpu_time_used1);
}
else {
printf("Functional Oriented Approach was faster by %.*e\n", cpu_time_used1 - cpu_time_used2);
}
getchar();
return 0;
}
Each time a program starts, functional programming is always faster. The only reason I could think of is to get an extra layer of pointer through the structure to call the method, but I would think that the inline would reduce this delay.
, , , / , ?