Following a brief IRC chat and seeing some commits go through that replaced new/memset with calloc, I wanted to write up a quick test.

Obviously from a C++ background I'd prefer not to use calloc/free.

In fact my first reaction is to use std::vector. In order to test timings I make a quick test (the attached memtest.cpp file).

tim@elwood:~/sandbox$ g++ --std=c++0x memtest.cpp -o memtest -lrt
tim@elwood:~/sandbox$ ./memtest
Testing 100000 iterations of 100 chars.
        new then memset 0.00980978s
        calloc then free 0.00437177s
        vector 0.0157277s
Testing 100000 iterations of 1000 chars.
        new then memset 0.00911948s
        calloc then free 0.00863989s
        vector 0.0193271s
Testing 100000 iterations of 10000 chars.
        new then memset 0.0332187s
        calloc then free 0.0322801s
        vector 0.0433207s
Testing 100000 iterations of 100000 chars.
        new then memset 0.63054s
        calloc then free 0.628706s
        vector 0.642924s
Testing 100000 iterations of 1000000 chars.
        new then memset 6.24861s
        calloc then free 6.2351s
        vector 6.24997s
test 20.813s

We can see that calloc is faster only at small sizes. What's more, the overhead of using a std::vector decreases rapidly as the size gets larger. One advantage of using a std::vector is that the memory is released for you, no need to use delete or free.

Tim
#include <iostream>
#include <string>
#include <vector>

#include <time.h>
#include <stdlib.h>
#include <string.h>

class Timer
{
public:
  Timer(std::string const& output)
    : output_(output) 
    {
      ::clock_gettime(CLOCK_MONOTONIC, &tm_);
    }
  ~Timer() {
    timespec tm;
    ::clock_gettime(CLOCK_MONOTONIC, &tm);
    double total_time = (tm.tv_sec - tm_.tv_sec) +
      ((tm.tv_nsec - tm_.tv_nsec) / 1e9);
    std::cerr << output_ << " " <<  total_time << "s\n";
  }
private:
  std::string output_;
  timespec tm_;
};

int main()
{
  Timer t("test");

  const int count = 100000;

  for (auto size : {100, 1000, 10000, 100000, 1000000}) {

    std::cerr << "Testing " << count << " iterations of " << size << " chars.\n";
    {
      Timer t("\tnew then memset");
      for (int i = 0; i < count; ++i) {
        char* c = new char[size];
        memset(c, 0, size);
        delete [] c;
      }
    }
    {
      Timer t("\tcalloc then free");
      for (int i = 0; i < count; ++i) {
        char* c = (char*)calloc(size, sizeof(char));
        free(c);
      }
    }
    {
      Timer t("\tvector");
      for (int i = 0; i < count; ++i) {
        std::vector<char> v(size);
      }
    }
  }
}

_______________________________________________
Mailing list: https://launchpad.net/~ayatana-dev
Post to     : ayatana-dev@lists.launchpad.net
Unsubscribe : https://launchpad.net/~ayatana-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to