Following this question I've found that std::list, forward_list in libstdc++ memory inefficient for smallish items. Is there any other competitive free implementation available in this case?
#include "malloc.h"
#include <forward_list>
#include <iomanip>
#include <iostream>
#include <list>
#include <memory>
#include <vector>
#define NUM_BYTES 1024
#define WIDTH 30
using namespace std;
struct Test {
struct mallinfo before_alloc;
struct mallinfo after_alloc;
Test() {
cout << setw(WIDTH) << "num bytes to be allocated " << NUM_BYTES
<< endl;
}
~Test() { cout << "done!" << endl; }
void singly_malloc() {
before_alloc = mallinfo();
void *chs[NUM_BYTES];
for (int i = 0; i < NUM_BYTES; ++i) {
chs[i] = malloc(sizeof(char));
}
after_alloc = mallinfo();
cout << setw(WIDTH) << "actual singly_malloc "
<< (after_alloc.uordblks - before_alloc.uordblks) << endl;
for (int i = 0; i < NUM_BYTES; ++i) {
free(chs[i]);
}
}
void bulk_malloc() {
before_alloc = mallinfo();
auto chs = malloc(sizeof(char) * NUM_BYTES);
after_alloc = mallinfo();
cout << setw(WIDTH) << "actual bulk_malloc "
<< (after_alloc.uordblks - before_alloc.uordblks) << endl;
free(chs);
}
void singly_alloc() {
before_alloc = mallinfo();
shared_ptr<char> chs[NUM_BYTES];
for (int i = 0; i < NUM_BYTES; ++i) {
chs[i] = make_shared<char>();
}
after_alloc = mallinfo();
cout << setw(WIDTH) << "actual singly_alloc "
<< (after_alloc.uordblks - before_alloc.uordblks) << endl;
}
void bulk_alloc() {
before_alloc = mallinfo();
vector<char> chs(NUM_BYTES);
after_alloc = mallinfo();
cout << setw(WIDTH) << "actual bulk_alloc "
<< (after_alloc.uordblks - before_alloc.uordblks) << endl;
}
void bulk_but_singly_alloc() {
before_alloc = mallinfo();
list<char> chs(NUM_BYTES);
after_alloc = mallinfo();
cout << setw(WIDTH) << "actual bulk_but_singly_alloc "
<< (after_alloc.uordblks - before_alloc.uordblks) << endl;
}
void bulk_but_singly_alloc2() {
before_alloc = mallinfo();
forward_list<char> chs(NUM_BYTES);
after_alloc = mallinfo();
cout << setw(WIDTH) << "actual bulk_but_singly_alloc2 "
<< (after_alloc.uordblks - before_alloc.uordblks) << endl;
}
};
int main() {
Test t;
t.singly_malloc();
t.bulk_malloc();
t.singly_alloc();
t.bulk_alloc();
t.bulk_but_singly_alloc();
t.bulk_but_singly_alloc2();
}