目录
容器分类与各种测试
1. 容器的结构与分类
2. 测试程序的辅助函数
3. 使用容器array
4. 使用vector
5. 使用容器list
6. 使用容器forward_list
7. 使用容器deque
8. 使用容器multiset
9. 使用容器multimap
10.使用容器unordered_multiset
11.使用容器unordered_multimap
12.使用容器set
13.使用容器map
14.使用容器unordered_set
15.使用容器unordered_map
16.使用容器hash_multiset
17.使用容器hash_multimap
18.使用容器heap(容器适配器)
分配器测试
容器分类与各种测试
1.容器的结构与分类
Sequence Containers(顺序容器): 快速顺序访问元素
- Array: C++11新特新,将语言的数组封装成Class,大小固定;
- Vector: 前端固定不变,连续内存空间,后端可以自动增长[分配器处理内存空间,增长速率为2^n];
- Deque: 双向队列,连续内存空间,两端可进可出;
- List: 双向链表,内存空间不连续;
- Forward-List:C++11新特新,单项链表,内存空间不连续,同等数据,内存空间小于List。
Associative Containers(关联容器):支持高效的关键字查找和访问
- Set/Multiset:编译器一般用红黑树实现,每一个结点为key;Set中结点key不可以重复,Multiset中结点key可以重复。
- Map/Multimap:编译器一般用红黑树实现,每一个结点中包含key-value,可以通过key来查找value;Map中结点key不可以重复,Multimap中结点key可以重复。
Unordered Containers(无序容器):通过HashTable实现
2. 测试程序的辅助函数
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib> // RAND_MAX
using namespace std;
// 输入最大值, RAND_MAX
long get_a_target_long()
{
long target = 0;
cout << "target (0~" << RAND_MAX << "):";
cin >> target;
return target;
}
// 将数值转化为string
string get_a_target_string()
{
int target = 0;
char buf[10];
cout << "target (0~" << RAND_MAX << "):";
cin >> target;
snprintf(buf, 10, "%d", target);
return string(buf);
}
// 比较两个long是否相等
int compare_longs(const void* a, const void* b) // 没有理解为什么return int
{
return ( *(long*)a - *(long*)b );
}
// 比较两个字符串是否相等
int compare_strings(const void* a, const void* b)
{
if ( *(string*)a > *(string*)b )
{
return 1;
}
else if ( *(string*)a < *(string*)b )
{
return -1;
}
else
{
return 0;
}
}
3. 使用容器array
#include <array>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include "assist.h"
using namespace std;
const long ASIZE = 500000;
void test_array()
{
cout << "test_array()............" << endl;
array<long, ASIZE> c;
clock_t timeStart = clock();
for(long i=0; i<ASIZE; ++i)
{
c[i] = rand() % 100000;
}
cout << "milli-seconds: " << (clock() - timeStart) << endl; // 赋值500000数据所用时间
cout << "array.size() = " << c.size() << endl;
cout << "array.front() = " << c.front() << endl; //Returns a reference to the first element in the array container
cout << "array.back() = " << c.back() << endl; // Returns a reference to the last element in the array container
cout << "array.data() = " << c.data() << endl; // Returns a pointer to the first element in the array object
long target = get_a_target_long(); // 输入一个目标数据
timeStart = clock();
qsort(c.data(), ASIZE, sizeof(long), compare_longs); // 快排
long *pItem = (long*) bsearch( // 二分查找
&target,
c.data(),
ASIZE,
sizeof(long),
compare_longs
);
cout << "qsort()+bsearch(), milli-seconds: "
<< clock() - timeStart
<< endl;
if (pItem != NULL)
{
cout << "found, " << *pItem << endl;
}
else
{
cout << "not found" << endl;
}
}
4. 使用vector
vector的空间增长以2的倍数增长,即由1->2->4->8->…->2n
如果不用,就会造成空间浪费。
#include <vector>
#include <stdexcept>
#include <string>
#include <cstdlib> // abort()
#include <cstdio> // snprintf()
#include <iostream>
#include <ctime>
#include <algorithm> // sort()
#include "assist.h"
using namespace std;
void test_vector(long& value)
{
cout << "test_vector......." << endl;
vector<string> c;
char buf[10];
clock_t timeStart = clock();
for(long i=0; i < value; ++i)
{
try{
snprintf(buf, 10, "%d", rand() % 10000);
c.push_back(string(buf));
}
catch(exception& p){
cout << "i=" << i << " " << p.what() << endl; // 内存不足,抛出异常
abort(); // 退出程序
}
}
cout << "milli-seconds: " << clock() - timeStart << endl;
cout << "vector.size() = " << c.size() << endl; // 容器中数据值的个数
cout << "vector.front() = " << c.front() << endl;
cout << "vector.back() = " << c.back() << endl;
cout << "vector.data() = " << c.data() << endl;
cout << "vector.capacity() = " << c.capacity() << endl; //容器的容量大小
// 查找给定元素
string target = get_a_target_string();
timeStart = clock();
vector<string>::iterator pItem = ::find(c.begin(), c.end(), target);
cout << "::find(), milli-second: " << clock() - timeStart << endl;
if ( pItem != c.end() )
{
cout << "found, " << *pItem << endl;
}
else
{
cout << "not found" << endl;
}
// 排序+二分查找
timeStart = clock();
sort(c.begin(), c.end()); // <algorithm>中的排序算法,时间复杂度为O(nlogn),应该为快排
string* pIt = (string*) bsearch(
&target,
c.data(),
c.size(),
sizeof(string),
compare_strings
);
cout << "sort() + bsearch(), milli-second: " << clock() - timeStart << endl;
if(pIt != NULL)
{
cout << "found, " << *pIt << endl;
}
else
{
cout << "not found" << endl;
}
}
int main()
{
long value = 1000000;
test_vector(value);
return 0;
}
5. 使用容器list
双向链表
每次扩充一个结点,结点很小,效率最高,空间利用率最高,但是找起来很慢。标准库的sort()和容器的sort()
通常容器提供的sort()更快
#include <list>
#include <string>
#include <ctime>
#include <stdexcept>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include "assist.h"
using namespace std;
void test_list(long& value)
{
cout << "test_list()......" << endl;
list<string> c;
char buf[10];
clock_t timeStart = clock();
for(long i=0; i<value; ++i)
{
try{
snprintf(buf, 10, "%d", rand() % 10000);
c.push_back(string(buf));
}
catch(exception& p){
cout << "i=" << i << p.what() << endl;
abort();
}
}
cout << "milli-seconds:" << clock() - timeStart << endl;
cout << "list.size()=" << c.size() << endl;
cout << "list.max_size()=" << c.max_size() << endl;
cout << "list.front()=" << c.front() << endl;
cout << "list.back()=" << c.back() << endl;
string target = get_a_target_string();
timeStart = clock();
list<string>::iterator pItem = ::find(c.begin(), c.end(), target); // 调用std的find()
cout << "::find(), milli-seconds:" << clock() - timeStart << endl;
if(pItem != c.end())
{
cout << "found, " << *pItem << endl;
}
else
{
cout << "not found" << endl;
}
timeStart = clock();
c.sort(); // 调用list中的sort()
cout << "c.sort(), milli-seconds:" << clock() - timeStart << endl;
}
int main()
{
long value = 1000000;
test_list(value);
return 0;
}
6.使用容器forward_list
单向链表,c++ 11标准新有
只有push_front() 因为只有一端,不提供另一端(太慢,就像vector)
不提供push_back(),back()
#include <forward_list>
#include <string>
#include <ctime>
#include <stdexcept>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include "assist.h"
using namespace std;
void test_forward_list(long& value)
{
cout << "test_forward_list()......" << endl;
forward_list<string> c;
char buf[10];
clock_t timeStart = clock();
for(long i=0; i<value; ++i)
{
try{
snprintf(buf, 10, "%d", rand() % 10000);
c.push_front(string(buf));
}
catch(exception& p){
cout << "i=" << i << p.what() << endl;
abort();
}
}
cout << "milli-seconds:" << clock() - timeStart << endl;
// cout << "list.size()=" << c.size() << endl;
cout << "list.max_size()=" << c.max_size() << endl;
cout << "list.front()=" << c.front() << endl;
// cout << "list.back()=" << c.back() << endl;
string target = get_a_target_string();
timeStart = clock();
forward_list<string>::iterator pItem = ::find(c.begin(), c.end(), target); // 调用std的find()
cout << "::find(), milli-seconds:" << clock() - timeStart << endl;
if(pItem != c.end())
{
cout << "found, " << *pItem << endl;
}
else
{
cout << "not found" << endl;
}
timeStart = clock();
c.sort(); // 调用list中的sort()
cout << "c.sort(), milli-seconds:" << clock() - timeStart << endl;
}
int main()
{
long value = 1000000;
test_forward_list(value);
return 0;
}
7. 使用容器deque
双向扩充,扩充时找到双倍大小的内存空间。
(buffer)分段连续,他是号称段与段之间是连续的,但这是假象,让使用者整个是连续的。继续放元素时,分配另外一个buffer,另外一个指针指向这个buffer。
左右指针,指向左右的buffer。每次扩充一个buffer。
#include <deque>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj05
{
void test_deque(long& value)
{
cout << "\ntest_deque().......... \n";
deque<string> c;
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.push_back(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "deque.size()= " << c.size() << endl;
cout << "deque.front()= " << c.front() << endl;
cout << "deque.back()= " << c.back() << endl;
cout << "deque.max_size()= " << c.max_size() << endl; //1073741821
string target = get_a_target_string();
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target);
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
timeStart = clock();
sort(c.begin(), c.end());
cout << "sort(), milli-seconds : " << (clock()-timeStart) << endl;
c.clear();
test_moveable(deque<MyString>(),deque<MyStrNoMove>(), value);
}
}
8.使用容器multiset
查找特别快,可以看成一个小型数据库。<使用红黑树>高度平衡树
没有push_back()和push_front()
只有insert,内部自动放在正确的位置。
#include <set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj06
{
void test_multiset(long& value)
{
cout << "\ntest_multiset().......... \n";
multiset<string> c;
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.insert(string(buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "multiset.size()= " << c.size() << endl;
cout << "multiset.max_size()= " << c.max_size() << endl; //214748364
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target); //比 c.find(...) 慢很多
cout << "std::find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
{
timeStart = clock();
auto pItem = c.find(target); //比 std::find(...) 快很多
cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
c.clear();
test_moveable(multiset<MyString>(),multiset<MyStrNoMove>(), value);
}
}
9.使用容器multimap
<使用红黑树>高度平衡树
没有push_back()和push_front()
只有insert,内部自动放在正确的位置。
c.insert(pair<type,type>(ct,ct));
不可以用下标!!因为有重复的key!
#include <map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj07
{
void test_multimap(long& value)
{
cout << "\ntest_multimap().......... \n";
multimap<long, string> c;
char buf[10];
clock_t timeStart = clock();
for(long i=0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
//multimap 不可使用 [] 做 insertion
c.insert(pair<long,string>(i,buf));
}
catch(exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock()-timeStart) << endl;
cout << "multimap.size()= " << c.size() << endl;
cout << "multimap.max_size()= " << c.max_size() << endl; //178956970
long target = get_a_target_long();
timeStart = clock();
auto pItem = c.find(target);
cout << "c.find(), milli-seconds : " << (clock()-timeStart) << endl;
if (pItem != c.end())
cout << "found, value=" << (*pItem).second << endl;
else
cout << "not found! " << endl;
c.clear();
}
}
10.使用容器unordered_multiset
<使用hash table>
#include <unordered_set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj08
{
void test_unordered_multiset(long& value)
{
cout << "\ntest_unordered_multiset().......... \n";
unordered_multiset<string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.insert(string(buf));
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
cout << "unordered_multiset.size()= " << c.size() << endl;
cout << "unordered_multiset.max_size()= " << c.max_size() << endl; //357913941
cout << "unordered_multiset.bucket_count()= " << c.bucket_count() << endl;
cout << "unordered_multiset.load_factor()= " << c.load_factor() << endl;
cout << "unordered_multiset.max_load_factor()= " << c.max_load_factor() << endl;
cout << "unordered_multiset.max_bucket_count()= " << c.max_bucket_count() << endl;
for (unsigned i = 0; i< 20; ++i) {
cout << "bucket #" << i << " has " << c.bucket_size(i) << " elements.\n";
}
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target); //比 c.find(...) 慢很多
cout << "std::find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
{
timeStart = clock();
auto pItem = c.find(target); //比 std::find(...) 快很多
cout << "c.find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
c.clear();
test_moveable(unordered_multiset<MyString>(), unordered_multiset<MyStrNoMove>(), value);
}
}
11.使用容器unordered_multimap
最适合搜寻大量元素
#include <unordered_map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj09
{
void test_unordered_multimap(long& value)
{
cout << "\ntest_unordered_multimap().......... \n";
unordered_multimap<long, string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
//multimap 不可使用 [] 進行 insertion
c.insert(pair<long, string>(i, buf));
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
cout << "unordered_multimap.size()= " << c.size() << endl;
cout << "unordered_multimap.max_size()= " << c.max_size() << endl; //357913941
long target = get_a_target_long();
timeStart = clock();
auto pItem = c.find(target);
cout << "c.find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, value=" << (*pItem).second << endl;
else
cout << "not found! " << endl;
}
}
12.使用容器set
<使用红黑树>
key一定要时独一无二的!!不可以重复!
#include <set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj13
{
void test_set(long& value)
{
cout << "\ntest_set().......... \n";
set<string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.insert(string(buf));
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
cout << "set.size()= " << c.size() << endl;
cout << "set.max_size()= " << c.max_size() << endl; //214748364
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target); //比 c.find(...) 慢很多
cout << "std::find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
{
timeStart = clock();
auto pItem = c.find(target); //比 std::find(...) 快很多
cout << "c.find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
}
}
13.使用容器map
<使用红黑树>
key一定要时独一无二的!!不可以重复!
#include <map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj14
{
void test_map(long& value)
{
cout << "\ntest_map().......... \n";
map<long, string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c[i] = string(buf);
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
cout << "map.size()= " << c.size() << endl;
cout << "map.max_size()= " << c.max_size() << endl; //178956970
long target = get_a_target_long();
timeStart = clock();
auto pItem = c.find(target);
cout << "c.find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, value=" << (*pItem).second << endl;
else
cout << "not found! " << endl;
c.clear();
}
}
14.使用容器unordered_set
<使用hash table>
#include <unordered_set>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj15
{
void test_unordered_set(long& value)
{
cout << "\ntest_unordered_set().......... \n";
unordered_set<string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c.insert(string(buf));
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
cout << "unordered_set.size()= " << c.size() << endl;
cout << "unordered_set.max_size()= " << c.max_size() << endl; //357913941
cout << "unordered_set.bucket_count()= " << c.bucket_count() << endl;
cout << "unordered_set.load_factor()= " << c.load_factor() << endl;
cout << "unordered_set.max_load_factor()= " << c.max_load_factor() << endl;
cout << "unordered_set.max_bucket_count()= " << c.max_bucket_count() << endl;
for (unsigned i = 0; i< 20; ++i) {
cout << "bucket #" << i << " has " << c.bucket_size(i) << " elements.\n";
}
string target = get_a_target_string();
{
timeStart = clock();
auto pItem = find(c.begin(), c.end(), target); //比 c.find(...) 慢很多
cout << "std::find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
{
timeStart = clock();
auto pItem = c.find(target); //比 std::find(...) 快很多
cout << "c.find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, " << *pItem << endl;
else
cout << "not found! " << endl;
}
}
}
15.使用容器unordered_map
<使用hash table>
#include <unordered_map>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <iostream>
#include <ctime>
namespace jj16
{
void test_unordered_map(long& value)
{
cout << "\ntest_unordered_map().......... \n";
unordered_map<long, string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
c[i] = string(buf);
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
cout << "unordered_map.size()= " << c.size() << endl; //357913941
cout << "unordered_map.max_size()= " << c.max_size() << endl;
long target = get_a_target_long();
timeStart = clock();
//! auto pItem = find(c.begin(), c.end(), target); //map 不適用 std::find()
auto pItem = c.find(target);
cout << "c.find(), milli-seconds : " << (clock() - timeStart) << endl;
if (pItem != c.end())
cout << "found, value=" << (*pItem).second << endl;
else
cout << "not found! " << endl;
}
}
16.使用容器hash_multiset
void test_hash_multiset(long& value)
{
cout << "\ntest_hash_multiset().......... \n";
__gnu_cxx::hash_multiset<string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
//! c.insert(string(buf));
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
}
17.使用容器hash_multimap
void test_hash_multimap(long& value)
{
cout << "\ntest_hash_multimap().......... \n";
__gnu_cxx::hash_multimap<long, string> c;
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", rand());
//c.insert(...
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "milli-seconds : " << (clock() - timeStart) << endl;
timeStart = clock();
//! auto ite = c.find(...
cout << "milli-seconds : " << (clock() - timeStart) << endl;
}
18.使用容器heap(容器适配器)
使用其他容器做底部支撑,不算是真正的容器,算是容器适配器
分配器测试
- 标准的分配器
Allocator
,#include<ext/...>
都是拓展的- 可以用不同的分配器测试同一容器
- 分配器
allocate() & deallocate()
进行内存的分配和释放,这样操作太麻烦了- 实际用到得
new delete malloc free
释放时并没有指定分配产生的字节
#include <list>
#include <stdexcept>
#include <string>
#include <cstdlib> //abort()
#include <cstdio> //snprintf()
#include <algorithm> //find()
#include <iostream>
#include <ctime>
#include <cstddef>
#include <memory> //內含 std::allocator
//欲使用 std::allocator 以外的 allocator, 得自行 #include <ext\...>
#ifdef __GNUC__
#include <ext\array_allocator.h>
#include <ext\mt_allocator.h>
#include <ext\debug_allocator.h>
#include <ext\pool_allocator.h>
#include <ext\bitmap_allocator.h>
#include <ext\malloc_allocator.h>
#include <ext\new_allocator.h>
#endif
namespace jj20
{
//pass A object to function template impl(),
//而 A 本身是個 class template, 帶有 type parameter T,
//那麼有無可能在 impl() 中抓出 T, 創建一個 list<T, A<T>> object?
//以下先暫時迴避上述疑問.
void test_list_with_special_allocator()
{
#ifdef __GNUC__
cout << "\ntest_list_with_special_allocator().......... \n";
//不能在 switch case 中宣告,只好下面這樣. //1000000次
list<string, allocator<string>> c1; //3140
list<string, __gnu_cxx::malloc_allocator<string>> c2; //3110
list<string, __gnu_cxx::new_allocator<string>> c3; //3156
list<string, __gnu_cxx::__pool_alloc<string>> c4; //4922
list<string, __gnu_cxx::__mt_alloc<string>> c5; //3297
list<string, __gnu_cxx::bitmap_allocator<string>> c6; //4781
int choice;
long value;
cout << "select: "
<< " (1) std::allocator "
<< " (2) malloc_allocator "
<< " (3) new_allocator "
<< " (4) __pool_alloc "
<< " (5) __mt_alloc "
<< " (6) bitmap_allocator ";
cin >> choice;
if (choice != 0) {
cout << "how many elements: ";
cin >> value;
}
char buf[10];
clock_t timeStart = clock();
for (long i = 0; i< value; ++i)
{
try {
snprintf(buf, 10, "%d", i);
switch (choice)
{
case 1: c1.push_back(string(buf));
break;
case 2: c2.push_back(string(buf));
break;
case 3: c3.push_back(string(buf));
break;
case 4: c4.push_back(string(buf));
break;
case 5: c5.push_back(string(buf));
break;
case 6: c6.push_back(string(buf));
break;
default:
break;
}
}
catch (exception& p) {
cout << "i=" << i << " " << p.what() << endl;
abort();
}
}
cout << "a lot of push_back(), milli-seconds : " << (clock() - timeStart) << endl;
//test all allocators' allocate() & deallocate();
int* p;
allocator<int> alloc1;
p = alloc1.allocate(1);
alloc1.deallocate(p, 1);
__gnu_cxx::malloc_allocator<int> alloc2;
p = alloc2.allocate(1);
alloc2.deallocate(p, 1);
__gnu_cxx::new_allocator<int> alloc3;
p = alloc3.allocate(1);
alloc3.deallocate(p, 1);
__gnu_cxx::__pool_alloc<int> alloc4;
p = alloc4.allocate(2);
alloc4.deallocate(p, 2); //我刻意令參數為 2, 但這有何意義!! 一次要 2 個 ints?
__gnu_cxx::__mt_alloc<int> alloc5;
p = alloc5.allocate(1);
alloc5.deallocate(p, 1);
__gnu_cxx::bitmap_allocator<int> alloc6;
p = alloc6.allocate(3);
alloc6.deallocate(p, 3); //我刻意令參數為 3, 但這有何意義!! 一次要 3 個 ints?
#endif
}
}