このような比較チャートが見つからない場合、代替手段は、問題のSTLクラスに独自のアロケーターを挿入し、ログを追加することです。
私がテストした実装(VC 8.0)は、string / vector / dequeを宣言するだけでメモリ割り当てを使用しませんが、リストとマップを行います。3文字を追加しても割り当てがトリガーされないため、文字列には短い文字列最適化があります。コードの下に出力が追加されます。
// basic allocator implementation used from here
// http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4079
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <map>
template <class T> class my_allocator;
// specialize for void:
template <>
class my_allocator<void>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
// reference to void members are impossible.
typedef void value_type;
template <class U>
struct rebind
{
typedef my_allocator<U> other;
};
};
#define LOG_ALLOC_SIZE(call, size) std::cout << " " << call << " " << std::setw(2) << size << " byte" << std::endl
template <class T>
class my_allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U>
struct rebind
{
typedef my_allocator<U> other;
};
my_allocator() throw() : alloc() {}
my_allocator(const my_allocator&b) throw() : alloc(b.alloc) {}
template <class U> my_allocator(const my_allocator<U>&b) throw() : alloc(b.alloc) {}
~my_allocator() throw() {}
pointer address(reference x) const { return alloc.address(x); }
const_pointer address(const_reference x) const { return alloc.address(x); }
pointer allocate(size_type s,
my_allocator<void>::const_pointer hint = 0) { LOG_ALLOC_SIZE("my_allocator::allocate ", s * sizeof(T)); return alloc.allocate(s, hint); }
void deallocate(pointer p, size_type n) { LOG_ALLOC_SIZE("my_allocator::deallocate", n * sizeof(T)); alloc.deallocate(p, n); }
size_type max_size() const throw() { return alloc.max_size(); }
void construct(pointer p, const T& val) { alloc.construct(p, val); }
void destroy(pointer p) { alloc.destroy(p); }
std::allocator<T> alloc;
};
int main(int argc, char *argv[])
{
{
typedef std::basic_string<char, std::char_traits<char>, my_allocator<char> > my_string;
std::cout << "===============================================" << std::endl;
std::cout << "my_string ctor start" << std::endl;
my_string test;
std::cout << "my_string ctor end" << std::endl;
std::cout << "my_string add 3 chars" << std::endl;
test = "abc";
std::cout << "my_string add a huge number of chars chars" << std::endl;
test += "d df uodfug ondusgp idugnösndögs ifdögsdoiug ösodifugnösdiuödofu odsugöodiu niu od unoudö n nodsu nosfdi un abc";
std::cout << "my_string copy" << std::endl;
my_string copy = test;
std::cout << "my_string copy on write test" << std::endl;
copy[3] = 'X';
std::cout << "my_string dtors start" << std::endl;
}
{
std::cout << std::endl << "===============================================" << std::endl;
std::cout << "vector ctor start" << std::endl;
std::vector<int, my_allocator<int> > v;
std::cout << "vector ctor end" << std::endl;
for(int i = 0; i < 5; ++i)
{
v.push_back(i);
}
std::cout << "vector dtor starts" << std::endl;
}
{
std::cout << std::endl << "===============================================" << std::endl;
std::cout << "deque ctor start" << std::endl;
std::deque<int, my_allocator<int> > d;
std::cout << "deque ctor end" << std::endl;
for(int i = 0; i < 5; ++i)
{
std::cout << "deque insert start" << std::endl;
d.push_back(i);
std::cout << "deque insert end" << std::endl;
}
std::cout << "deque dtor starts" << std::endl;
}
{
std::cout << std::endl << "===============================================" << std::endl;
std::cout << "list ctor start" << std::endl;
std::list<int, my_allocator<int> > l;
std::cout << "list ctor end" << std::endl;
for(int i = 0; i < 5; ++i)
{
std::cout << "list insert start" << std::endl;
l.push_back(i);
std::cout << "list insert end" << std::endl;
}
std::cout << "list dtor starts" << std::endl;
}
{
std::cout << std::endl << "===============================================" << std::endl;
std::cout << "map ctor start" << std::endl;
std::map<int, float, std::less<int>, my_allocator<std::pair<const int, float> > > m;
std::cout << "map ctor end" << std::endl;
for(int i = 0; i < 5; ++i)
{
std::cout << "map insert start" << std::endl;
std::pair<int, float> a(i, (float)i);
m.insert(a);
std::cout << "map insert end" << std::endl;
}
std::cout << "map dtor starts" << std::endl;
}
return 0;
}
これまでにテストされたVC8とSTLPort 5.2は、ここに比較があります(テストに含まれる:文字列、ベクトル、両端キュー、リスト、マップ)
Allocation on declare Overhead List Node Overhead Map Node
VC8 map, list 8 Byte 16 Byte
STLPort 5.2 (VC8) deque 8 Byte 16 Byte
Paulhodge's EASTL (none) 8 Byte 16 Byte
VC8出力文字列/ベクトル/ deque / list / map:
===============================================
my_string ctor start
my_string ctor end
my_string add 3 chars
my_string add a huge number of chars chars
my_allocator::allocate 128 byte
my_string copy
my_allocator::allocate 128 byte
my_string copy on write test
my_string dtors start
my_allocator::deallocate 128 byte
my_allocator::deallocate 128 byte
===============================================
vector ctor start
vector ctor end
my_allocator::allocate 4 byte
my_allocator::allocate 8 byte
my_allocator::deallocate 4 byte
my_allocator::allocate 12 byte
my_allocator::deallocate 8 byte
my_allocator::allocate 16 byte
my_allocator::deallocate 12 byte
my_allocator::allocate 24 byte
my_allocator::deallocate 16 byte
vector dtor starts
my_allocator::deallocate 24 byte
===============================================
deque ctor start
deque ctor end
deque insert start
my_allocator::allocate 32 byte
my_allocator::allocate 16 byte
deque insert end
deque insert start
deque insert end
deque insert start
deque insert end
deque insert start
deque insert end
deque insert start
my_allocator::allocate 16 byte
deque insert end
deque dtor starts
my_allocator::deallocate 16 byte
my_allocator::deallocate 16 byte
my_allocator::deallocate 32 byte
===============================================
list ctor start
my_allocator::allocate 12 byte
list ctor end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list dtor starts
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
===============================================
map ctor start
my_allocator::allocate 24 byte
map ctor end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map dtor starts
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
STLPort 5.2。VC8でコンパイルされた出力
===============================================
my_string ctor start
my_string ctor end
my_string add 3 chars
my_string add a huge number of chars chars
my_allocator::allocate 115 byte
my_string copy
my_allocator::allocate 115 byte
my_string copy on write test
my_string dtors start
my_allocator::deallocate 115 byte
my_allocator::deallocate 115 byte
===============================================
vector ctor start
vector ctor end
my_allocator::allocate 4 byte
my_allocator::deallocate 0 byte
my_allocator::allocate 8 byte
my_allocator::deallocate 4 byte
my_allocator::allocate 16 byte
my_allocator::deallocate 8 byte
my_allocator::allocate 32 byte
my_allocator::deallocate 16 byte
vector dtor starts
my_allocator::deallocate 32 byte
===============================================
deque ctor start
my_allocator::allocate 32 byte
my_allocator::allocate 128 byte
deque ctor end
deque insert start
deque insert end
deque insert start
deque insert end
deque insert start
deque insert end
deque insert start
deque insert end
deque insert start
deque insert end
deque dtor starts
my_allocator::deallocate 128 byte
my_allocator::deallocate 32 byte
===============================================
list ctor start
list ctor end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list dtor starts
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
===============================================
map ctor start
map ctor end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map dtor starts
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
EASTLの結果、dequeは使用不可
===============================================
my_string ctor start
my_string ctor end
my_string add 3 chars
my_allocator::allocate 9 byte
my_string add a huge number of chars chars
my_allocator::allocate 115 byte
my_allocator::deallocate 9 byte
my_string copy
my_allocator::allocate 115 byte
my_string copy on write test
my_string dtors start
my_allocator::deallocate 115 byte
my_allocator::deallocate 115 byte
===============================================
vector ctor start
vector ctor end
my_allocator::allocate 4 byte
my_allocator::allocate 8 byte
my_allocator::deallocate 4 byte
my_allocator::allocate 16 byte
my_allocator::deallocate 8 byte
my_allocator::allocate 32 byte
my_allocator::deallocate 16 byte
vector dtor starts
my_allocator::deallocate 32 byte
===============================================
list ctor start
list ctor end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list insert start
my_allocator::allocate 12 byte
list insert end
list dtor starts
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
my_allocator::deallocate 12 byte
===============================================
map ctor start
map ctor end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map insert start
my_allocator::allocate 24 byte
map insert end
map dtor starts
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
my_allocator::deallocate 24 byte
deque
、ベクターを使用してSTLに常に実装されているという印象を受けていました。