Thanks for the explanations :-)
I have made a test, where I want to look at how expensive it is to call reserve() and clear().
The test setup is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
#include <iostream>
#include <sys/time.h>
#include <time.h>
#include <sys/timeb.h>
#include <vector>
#define MY_RAND_MAX 32767
int myrand(unsigned long *next) {
*next = *next * 1103515245 + 12345;
return((unsigned)(*next/65536) % 32768);
}
float rand01(unsigned long *next) {
return( ((float)myrand(next))/((float)MY_RAND_MAX+1) );
}
/* ---TIME ------------------------------
* Evaluated time for program in secunds
* and milliseconds.
*/
struct timeb timebuffer;
struct a_time {
time_t time_s;
unsigned short time_ms;
};
a_time startTime() {
ftime( &timebuffer );
a_time st;
st.time_s = timebuffer.time;
st.time_ms = timebuffer.millitm;
return(st);
}
void endTime(a_time &st) {
ftime( &timebuffer );
a_time end;
end.time_s = timebuffer.time;
end.time_ms = timebuffer.millitm;
if(end.time_ms - st.time_ms < 0) {
end.time_s = end.time_s - st.time_s - 1;
end.time_ms = 1000 + (end.time_ms - st.time_ms);
}
else {
end.time_s = end.time_s - st.time_s;
end.time_ms = end.time_ms - st.time_ms;
}
std::cout << "\nTotal time : " << end.time_s << "." << end.time_ms << std::endl;
}
int main(void) {
struct a_time t_begin;
std::vector <float> my_vector;
unsigned long next = 1;
unsigned int size;
unsigned int max_size = 1000000;
unsigned int max_loop = 5000;
// ------------------------------------------
t_begin = startTime();
my_vector.reserve(size);
for(unsigned i=0;i<max_loop;i++) {
size = (unsigned int)(rand01(&next)*max_size);
for(unsigned j=0;j<size;j++) {
my_vector.push_back(rand01(&next));
}
my_vector.clear();
}
std::cout << "With reserve(), clear():";
endTime(t_begin);
// ------------------------------------------
next = 1;
my_vector.clear();
t_begin = startTime();
for(unsigned i=0;i<max_loop;i++) {
size = (unsigned int)(rand01(&next)*max_size);
my_vector.reserve(size);
for(unsigned j=0;j<size;j++) {
my_vector.push_back(rand01(&next));
}
std::vector <float>().swap(my_vector);
}
std::cout << "With reserve(), swap():";
endTime(t_begin);
// ------------------------------------------
next = 1;
my_vector.clear();
unsigned int my_vector_pos;
t_begin = startTime();
my_vector.resize(max_size);
for(unsigned i=0;i<max_loop;i++) {
size = (unsigned int)(rand01(&next)*max_size);
my_vector_pos = 0;
for(unsigned j=0;j<size;j++) {
my_vector[j] = (rand01(&next));
my_vector_pos++;
}
}
std::cout << "Just overwriting..:";
endTime(t_begin);
// ------------------------------------------
return(0);
}
| |
I have tested it on a laptop with a single core at 1.73 Ghz and with 4Gb RAM.
I have compiled the program witn -O2 flag.
The result is:
With reserve(), clear():
Total time : 44.376
With reserve(), swap():
Total time : 52.693
Just overwriting..:
Total time : 36.174
To explain the
std::vector <float>().swap(my_vector)
is that the constructor creates a new empty container on the fly and swap it with the old one. Then call the destructor on the old one. This case should perform the worst time, and it does.
The question is, why are there 8 seconds between just overwriting the elements in the container and using clear()?
I'm not sure if it is the call of clear() that do the difference.
I have tried to put reserve() before the outer loop in test 1 (with reserve(), clear()) without significant change in the time consumed.
So at that point you have right.
Maybe it could be some sort of cache optimization using the overwriting scheme. Nonetheless, I think I stick to the first one with reserve(), clear().
Thanks for your help.