Skip to content

C slow function call

An answer to this question on Stack Overflow.

Question

How can i have my functions in another c file without losing execution time ?

strcpy:                 0.485000
strcpyFunc:             0.469000
strcpyFuncInAnotherC:   2.015000

Have even tried with inline, but it seem it have never inline anything because the exe file keep his small size, and time were the same.

I compile with mingw32-gcc under code::block

Im learning C, many thanks for helping me understanding how to right handle a project with many .c files...

Here the bench code (have done without main.h)

main.c

#include <stdio.h>
#include <string.h>
#include <windows.h>//for GetTickCount
#include "func.h"
void double2str(const double x, char *buf) {
	sprintf(buf, "%.6f", x);
	}
double milliTick(void) {
	return GetTickCount()/1000.0;
	}
double timeDiff(const double start, const double end) {
	return end-start;
	}
void strcpyFunc(char *buf, const char *str) {
	strcpy(buf, str);
	}
int main() {
	char buf64[24];
	char buf[1024];
	char bufBench[32];
	char *sample = "abcdefghijklmnopqrstuvwxyz";
	double timeStart1=0, timeEnd1=0;
	double timeStart2=0, timeEnd2=0;
	double timeStart3=0, timeEnd3=0;
	size_t len = 99999999;
	size_t i = 0;
	timeStart1 = milliTick();
	while(i < len) {
		strcpy(bufBench, sample);
		i++;
		}
	timeEnd1 = milliTick();
	i = 0;
	timeStart2 = milliTick();
	while(i < len) {
		strcpyFunc(bufBench, sample);
		i++;
		}
	timeEnd2 = milliTick();
	i = 0;
	timeStart3 = milliTick();
	while(i < len) {
		strcpyFuncInAnotherC(bufBench, sample);
		i++;
		}
	timeEnd3 = milliTick();
    
	strcpy(buf, "");
	double2str(timeDiff(timeStart1,timeEnd1), buf64);
	strcat(buf, "strcpy:\t\t\t");
	strcat(buf, buf64);
	strcat(buf, "\n");
	double2str(timeDiff(timeStart2,timeEnd2), buf64);
	strcat(buf, "strcpyFunc:\t\t");
	strcat(buf, buf64);
	strcat(buf, "\n");
	double2str(timeDiff(timeStart3,timeEnd3), buf64);
	strcat(buf, "strcpyFuncInAnotherC:\t");
	strcat(buf, buf64);
	strcat(buf, "\n");
    printf(buf);
    return 0;
	}

func.h

#ifndef HEADER_FUNC_H
#define HEADER_FUNC_H
void strcpyFuncInAnotherC(char *buf, const char *str);
#endif

func.c

#include <stdio.h>
#include <string.h>
#include "func.h"
void strcpyFuncInAnotherC(char *buf, const char *str) {
	strcpy(buf, str);
	}

Answer

If you are compiling to object files, ala:

gcc -O3 -o main.o main.c
gcc -O3 -o func.o func.c
gcc -O3 -o a.out main.o func.o

Then the compiler will optimize each object file (main and func), but cannot optimize the files when they're pieced together.

There's a reason for this: some projects have hundreds of object files and doing global optimization would greatly increase compile times. This, in turn, would make iterative testing difficult.

You can, however, force what's called "link-time" or "interprocedural" optimization:

gcc -O3 -flto -o main.o main.c
gcc -O3 -flto -o func.o func.c
gcc -O3 -flto -o a.out main.o func.o

The compiler should now behave as if all the code had been in one source file to begin with. (-flto stands for "link-time optimization")