unity-dev team mailing list archive
-
unity-dev team
-
Mailing list archive
-
Message #00288
[Ayatana-dev] C++ memory allocation
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);
}
}
}
}
Follow ups