Allocate and free memory VS. allocate first, process only for each time


Once upon a time, I was trying to write some code for some robot hardware's serial communication part. I had a desktop pc, no memory restrictions (8GB RAM, i3 CPU etc.) and that particular program communicated with microcontroller via USB(Fullspeed) or Serial with 115200 baudrate.

I had around 20 to 30 methods which used this communication function and because of that I was really curious how its processing time affected my work..

Only one instance of this function is running at the same time. The question is... Which one is more effective to process data faster?

1. Define first, use every time;
...
private:
    struct timespec ctv1, ctv2;
    double time_diff;
    int serial_write_ret;
    int ret_val;
...
int MSerial::genAndSend_setInt32Command() 
{
    genSum ( stm_buf_t );
    sem_wait ( &serial_mutex );
    // someFunctions();
    sem_post ( &serial_mutex );
    return ret_val;
}

2. Or allocate and deallocate every time;
int MSerial::genAndSend_setInt32Command()
{
    genSum ( stm_buf_t );
    struct timespec ctv1, ctv2;
    double time_diff = .0;
    int serial_write_ret;
    int ret_val = TIMEOUT_ERROR_IN_SERIAL;

    sem_wait ( &serial_mutex );
    // someFunction();
    sem_post ( &serial_mutex );
    return ret_val;
}


My laziness...

Then I decided to be a little less lazy 😄 I should have done in the beginning, but of course I took the easy route first.

And wrote the example code.

First I've writed "Allocate - Deallocate every time" class:
class AllocEvery
{
public:

    int doSomething()
    {
        double pi, gold, ogh;
        std::string den_rit, jobs, bill;
        char c_str[64];

        pi   = 3.1415926535;
        gold = 1.6180339887;
        ogh  = 0.0000000033;
        ogh += pi;
        ogh += gold;
        jobs = "Being the richest man in the cemetery doesn't matter to me. Going to bed at night saying we've done something wonderful, that's what matters to me.";
        bill = "Your most unhappy customers are your greatest source of learning.";
        den_rit = "UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity.";
    }
};

Then, Process only:
class ProcessOnly
{
public:

    double pi, gold, ogh;
    std::string den_rit, jobs, bill;
    char c_str[64];

    int doSomething()
    {
        pi   = 3.1415926535;
        gold = 1.6180339887;
        ogh  = 0.0000000033;
        ogh += pi;
        ogh += gold;
        jobs = "Being the richest man in the cemetery doesn't matter to me. Going to bed at night saying we've done something wonderful, that's what matters to me.";
        bill = "Your most unhappy customers are your greatest source of learning.";
        den_rit = "UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity.";
    }
};

And, in main, I used these classes in the same way, and tried which one is faster;
int main ( int argc, char **argv )
{
    int max = 80 * 60 * 5; // Rate * Seconds * Minutes
    struct timespec time1, time2;
    double time_diff = .0;
    AllocEvery obj; /// ProcessOnly obj;

    clock_gettime ( CLOCK_MONOTONIC, &time1 );

    for (int i = 0; i < max; i++)
    {
        obj.doSomething();
    }

    clock_gettime ( CLOCK_MONOTONIC, &time2 );

    time_diff = time2.tv_sec - time1.tv_sec + ( time2.tv_nsec - time1.tv_nsec ) / BILLION;

//  std::cout << "Process only :: Elapsed time: " << time_diff << std::endl;
    std::cout << "AllocEvery :: Elapsed time: " << time_diff << std::endl;

return 0;
}

I called the same obj.doSomething(); function from them.

Different outputs of different executions:
ogh@ubuntu:~/C_denemeler/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.075384
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0741677
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.074426
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0740817
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0734898
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0747045
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0727975
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0772903
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./a.out
------------> Alloc - Dealloc Everytime:: Elapsed time: 0.0726992
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00806864
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00727956
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00202144
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00195636
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00203696
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00387936
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00276425
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00200299
ogh@ubuntu:~/C_Cpp_Examples/tryspeed_cpp$ ./p.out
------------>  Process only:: Elapsed time: 0.00207049

And This is the result:
Process only:: mean: 0.00356445 in seconds 
Alloc Dealloc:: mean: 0.0743379 in seconds

of period of  80 * 60 * 60  (Hz x Seconds x Minutes).

Full source is on github;
https://github.com/cosmicog/C_Cpp_Examples/tree/master/tryspeed_cpp

Comments