(二)容器和分配器各种测试

目录

容器分类与各种测试

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(顺序容器): 快速顺序访问元素

  1. Array:           C++11新特新,将语言的数组封装成Class,大小固定;
  2. Vector:         前端固定不变,连续内存空间,后端可以自动增长[分配器处理内存空间,增长速率为2^n];
  3. Deque:         双向队列,连续内存空间,两端可进可出;
  4. List:              双向链表,内存空间不连续;
  5. Forward-List:C++11新特新,单项链表,内存空间不连续,同等数据,内存空间小于List。

Associative Containers(关联容器):支持高效的关键字查找和访问

  1. Set/Multiset:编译器一般用红黑树实现,每一个结点为key;Set中结点key不可以重复,Multiset中结点key可以重复。
  2. 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

5600819-46b4a614eb643315.png

test_array.cpp

#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

5600819-8e5c8c04e4e44d16.png

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

5600819-6750aa87f1d9cc38.png

双向链表
每次扩充一个结点,结点很小,效率最高,空间利用率最高,但是找起来很慢。 

标准库的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

5600819-24be7bdedb875380.png

单向链表,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

5600819-4c1f3333bff9c8cd.png

双向扩充,扩充时找到双倍大小的内存空间。
(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 			
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值