-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
int_vector is substantially slower than std::vector #43
Comments
The function sdsl-lite/include/sdsl/int_vector.hpp Line 787 in 9930944
Here is a benchmark using the slow #include <iostream>
#include <chrono>
#include <sdsl/bit_vectors.hpp>
#include <vector>
using namespace std;
using namespace sdsl;
void run_benchmark(){
size_t num_runs = 1000 * 1000;
int_vector<64> values;
values.reserve(num_runs);
chrono::steady_clock::time_point begin = chrono::steady_clock::now();
for (size_t i = 0; i < num_runs; i++){
values.amortized_resize(i + 1);
// Uncomment to make it go fast.
//values.m_width = 64;
auto end = int_vector_trait<64>::end(&values, values.m_data, (values.m_size / values.m_width));
*(end - 1) = i;
}
chrono::steady_clock::time_point end = chrono::steady_clock::now();
double mean = chrono::duration_cast<chrono::nanoseconds> (end - begin).count() / (double)num_runs;
cout << "On average, it took " << mean << " nanoseconds to push_back one value." << endl;
}
int main(){
// Run benchmark a few times just to be sure.
for (size_t i = 0; i < 9; i++){
cout << "Run " << i + 1 << ": ";
run_benchmark();
}
return 0;
} And here are the results on my computer:
And after uncommenting the line
I do not understand why |
I haven't double-checked this, but it seems like an easy fix. @eseiler what do you think? |
I just checked. The width can be dynamic: sdsl-lite/include/sdsl/int_vector.hpp Lines 246 to 247 in 9930944
sdsl-lite/include/sdsl/int_vector.hpp Line 625 in 9930944
sdsl-lite/include/sdsl/int_vector.hpp Lines 126 to 136 in 9930944
So removing m_width is not an option. However, replacing: sdsl-lite/include/sdsl/int_vector.hpp Line 787 in 9930944
with the following should work: iterator end() noexcept
{
if constexpr (t_width == 0) // dynamic width
return int_vector_trait<t_width>::end(this, m_data, (m_size / m_width));
else
return int_vector_trait<t_width>::end(this, m_data, (m_size / t_width));
} |
Sorry for the late reply, I was sick :( Yes, we need both, as the bitvector may be dynamic. |
@eseiler I get around 3.5 ns with the linked benchmark and 2 ns after replacing |
Thanks for the feedback, @99991 ! I tweaked it a bit more. The benchmark now uses random values. I think I'm going ahead and merge #102 as it already improves the performance quite a lot. Another thing to test would be the One thing to note is that the benchmark is a microbenchmark, and even with a moderately sized vector (in the benchmark it's 64 million elements, so it should avoid most cache effects), the numbers fluctuate quite a bit. |
Even if the entire amount of storage is pre-reserved (no memory allocations) calling push_back on the sdsl vector is substantially slower that doing the same on std::vector (up to 10x slower).
(the fourth column is number of iterations performed in fixed amount of time)
I thought that, especially, for the builtin integer types this shouldn't be so noticeable?
The text was updated successfully, but these errors were encountered: