The performance comparisons among std::list deque vector
Hi!
For a long time I am confused about the performance of list deque
vector, I had thought that each of them have their strong point and weak
point also. So we should choose container carefully. Some rules may like: if
there is insert or remove in the middle, no vector.
These rules is not pragmatic sometime I realize, finally I do a test
below(vc 2008 sp1, define /D _SECURE_SCL=0 ). If the element < 10000
(normally it is the real case), the vector is much better than list or deque
even insert or remove in the middle.
I think this is because memory alloc and free is much cost than the
algorithm O(0) or O(n), Am I right? or something missed?
mos.
some result I list here:
....
push 10000 loop 0 num_remove 0 remove times 0
cost list: 3 sum 0
cost deque: 1 sum 0
cost vector: 0 sum 0
....
test push 10000 loop 10000 num_remove 0 remove times 0
cost list: 280 sum 652302704
cost deque: 335 sum 603232704
cost vector: 58 sum 654802704
....
test push 0 loop 0 num_remove 10000 remove times 100000
cost list: 3502 sum 0
cost deque: 4897 sum 0
cost vector: 858 sum 0
and the code:
#include <windows.h>
struct st_cost
{
public:
LARGE_INTEGER g_Frequency;
__int64 m_start;
__int64 m_end;
st_cost(){
QueryPerformanceFrequency(&g_Frequency);
}
void start(){
LARGE_INTEGER t;
QueryPerformanceCounter(&t);
m_start = t.QuadPart;
}
void end(){
LARGE_INTEGER t1;
QueryPerformanceCounter(&t1);
m_end = t1.QuadPart;
}
int get_cost_this() const{
return (m_end - m_start) * 1000 / g_Frequency.QuadPart;
}
};
struct st_cost_guide
{
public:
st_cost& m_cost;
st_cost_guide(st_cost& cost):m_cost(cost){m_cost.start();}
~st_cost_guide(){m_cost.end();}
};
#include <list>
#include <vector>
#include <deque>
#include <algorithm>
#include <iostream>
using namespace std;
template<class T, class A>
bool remove_container(T& t, A a)
{
T::iterator it = std::find(t.begin(),t.end(),a);
if (it != t.end())
{
t.erase(it);
return true;
}
return false;
}
template<typename T>
int test_container_pushback(int n,T& t)
{
for (int i=0; i<n; i++)
{
t.push_back(rand() % 100);
}
return 0;
}
template<typename T>
int test_container_loop(int loop,T& t)
{
int sum = 0;
for (int i=0; i<loop; i++)
{
T::iterator e = t.end();
for (T::iterator it = t.begin(); it != e; ++it)
{
sum += *it;
}
}
return sum;
}
template<typename T>
int test_remove_and_pushback(int num ,int remove ,T& t)
{
t.clear();
for (int i=0; i<num; i++)
{
t.push_back(i);
}
for (int i=0; i<remove; i++)
{
int r = rand() % num;
T::iterator it = std::find(t.begin(),t.end(),r);
if (it != t.end())
t.erase(it);
t.push_back(r);
}
return 0;
}
template<typename T>
int test_container(int n,int loop,int num ,int remove,T& test)
{
int sum = 0;
sum += test_container_pushback(n,test);
sum += test_container_loop(loop,test);
sum += test_remove_and_pushback(num,remove,test);
return sum;
}
int test(int n,int loop,int num_remove ,int remove)
{
cout << __FUNCTION__ << " push " << n << " loop " << loop << " num_remove
" << num_remove << " remove times " << remove << endl;
st_cost test;
int sum;
{
std::list<int> t;
st_cost_guide guid(test);
sum = test_container(n,loop,num_remove,remove,t);
}
cout << "cost list: " << test.get_cost_this() << " sum " << sum << endl;
{
std::deque<int> t;
st_cost_guide guid(test);
sum = test_container(n,loop,num_remove,remove,t);
}
cout << "cost deque: " << test.get_cost_this() << " sum " << sum << endl;
{
std::vector<int> t;
st_cost_guide guid(test);
sum = test_container(n,loop,num_remove,remove,t);
}
cout << "cost vector: " << test.get_cost_this() << " sum " << sum << endl
<< endl;
return 0;
}
void test_push_and_loop()
{
cout << __FUNCTION__ " start " << endl;
int n = 1;
int loop = 100000000;
for (int i=0; i<5; i++)
{
test(n,loop,0,0);
n *= 10;
loop /= 10;
}
cout << __FUNCTION__ " end " << endl << endl;
}
void test_push()
{
cout << __FUNCTION__ " start " << endl;
int n = 1;
int loop = 0;
for (int i=0; i<5; i++)
{
test(n,loop,0,0);
n *= 10;
}
cout << __FUNCTION__ " end " << endl << endl;
}
void test_remove()
{
cout << __FUNCTION__ " start " << endl;
int n = 1;
int loop = 100000;
for (int i=0; i<5; i++)
{
test(0,0,n,loop);
n *= 10;
}
cout << __FUNCTION__ " end " << endl << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
test_push();
test_push_and_loop();
test_remove();
return 0;
}