I was curious to see whether sorting a vector <vector<int>>
would be slower than sorting a vector <array <int, 3>>
. The dimensions of the vector
is 1000000 by 3, and below is my driver code implementing this:
#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector <vector<int>> v(1000000, vector <int> (3));
srand(time(nullptr));
for(int i = 0; i < 1000000; ++i){
for(int j = 0; j < 3; ++j){
v[i][j] = rand();
}
}
double start = clock();
sort(v.begin(), v.end());
cout << (clock()-start)/(CLOCKS_PER_SEC/1000) << endl;
return 0;
}
Compiling with g++ -O3 sorting_test.cxx
with gcc 7.5.0, I get a runtime of around 300 ms. Declaring v
as a vector <array <int, 3>>
halved the runtime to around 149 ms.
However, declaring v
as a vector <tuple<int, int, int>>
beat out both of the above options, with an average runtime of approximately 100 ms
.
I can somewhat understand why the array
option is faster than the vector
option (array
size is a constant expression, unlike the vector
), but I have no idea why the tuple
would beat both of them. Can somebody please explain this to me?
The code that fills the tuple <int, int, int>
s is
srand(time(nullptr));
for(int i = 0; i < 1000000; ++i){
get <0> (v[i]) = rand();
get <1> (v[i]) = rand();
get <2> (v[i]) = rand();
}
A std::vector can never be faster than an array, as it has (a pointer to the first element of) an array as one of its data members. But the difference in run-time speed is slim and absent in any non-trivial program. One reason for this myth to persist, are examples that compare raw arrays with mis-used std::vectors.
Vector is better for frequent insertion and deletion, whereas Arrays are much better suited for frequent access of elements scenario. Vector occupies much more memory in exchange for managing storage and growing dynamically, whereas Arrays are a memory-efficient data structure.
std::list , being a linked list, cannot provide random access to its elements efficiently. That's why it provides its own specialized sort algorithm.
Vector is faster for insertion and deletion of elements at the end of the container. Set is faster for insertion and deletion of elements at the middle of the container.
While the disassembly for the whole programs are too large, this demonstrates the core difference between operator<
for array
and tuple
: https://godbolt.org/z/h1Y33e
Essentially, in the tuple version, you have a fixed comparison of 3 elements whereas in the array version, you have a loop.
Though I'm surprised that the compiler did not unroll the loop.
Edit: looks like clang does optimize them to both, non-loop code: https://godbolt.org/z/cMExTb (I did not fully read it, but I only see forward jumps)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With