#c #stl
#c #stl
Вопрос:
В приведенном ниже примере я ожидал unordered_map
, что будет быстрее map
, но это не так. Почему это так? unordered_map
Предназначен для другой цели, а не для того, чтобы быть быстрее обычной карты?
#include <iostream>
#include <chrono>
#include <unordered_map>
#include <map>
int main()
{
std::unordered_map<int, double> grid_unmap_int;
std::map<int, double> grid_map_int;
size_t map_size = 1e7;
auto t1 = clock();
for (size_t i = 0; i < map_size; i) {
grid_unmap_int[i] = 1.0;
}
auto t2 = clock();
for (size_t k = 0; k < map_size; k) {
grid_map_int[k] = 1.0;
}
auto t3 = clock();
std::cout << "Insertion n";
std::cout << "Filling unordered map int key: " << (t2 - t1) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.n";
std::cout << "Filling map int key: " << (t3 - t2) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.n";
std::cout << std::endl;
t1 = clock();
for (size_t i = 0; i < map_size; i) {
double b = grid_unmap_int[i] ;
}
t2 = clock();
for (size_t k = 0; k < map_size; k) {
double b = grid_map_int[k];
}
t3 = clock();
std::cout << "Retrieve n";
std::cout << "Filling unordered map int key: " << (t2 - t1) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.n";
std::cout << "Filling map int key: " << (t3 - t2) / static_cast<double>(CLOCKS_PER_SEC) << " seconds.n";
return 0;
}
Редактировать:
результаты:
введите описание изображения здесь
Комментарии:
1.
unordered_map
он не предназначен для того, чтобы работать быстрее , чем обычная карта. Они работают по-разному. Точно так же, как вектор или список. Вы не можете назвать один из них самым быстрым или лучшим . У них есть сильные и слабые стороны, и какая из них использовать, зависит от вашего варианта использования.2. Вы заявляете о производительности без предоставления статистики или флагов компиляции.
3. быстрый тест предполагает, что на самом деле unordered_map в 5 раз быстрее для вашего конкретного тестового примера: quick-bench.com/q/OK0XfUYBuko17quF1edWLIgLdK8
4.Ваше утверждение, похоже, противоречит тому, что написано в cppreference. unordered_map — Поиск, вставка и удаление элементов имеют среднюю сложность постоянного времени.операции поиска, удаления и вставки карты имеют логарифмическую сложность.
5. Вы использовали
-O3
? В моей системе unordered_map в 2,8 раза быстрее для вставки и в 10 раз быстрее для извлечения.
Ответ №1:
В приведенном ниже примере я ожидал
unordered_map
, что будет быстрееmap
, но это не так. Почему это так?
Это может быть так, поскольку std::map
обещает логарифмическое время поиска, в то std::ordered_map
время как в среднем обещает постоянное время поиска, в худшем случае линейное по размеру контейнера.
Это причудливый способ сказать: «Могло быть лучше, а могло быть и хуже. Профилируйте его для вашего конкретного сценария «.
unordered_map
Предназначен ли он для другой цели, чем быть быстрее обычногоmap
?
ДА.
std::map
можно использовать только те ключи, которые заказаны. Должен быть устоявшийся способ сортировки типа, как int
в вашем примере. И в свою очередь, повторение std::map
дает вам такой порядок.
std::unordered_map
можно использовать только ключи, для которых std::hash<Key>
определено. Ключи не обязательно должны иметь установленный порядок (например, это могут быть изображения. Или цвета. Или звуки.) Но должен существовать какой-то способ преобразования значений в хэши.
Комментарии:
1. На самом деле сложность нам вообще мало что говорит. O(exp (n)) может быть быстрее, чем O (1) для всех достижимых n (например, n <= максимальный размер памяти), если с последним связана какая-то огромная константа. И это не какой-то абстрактный аргумент. Именно по этой причине, например, широко используется быстрая сортировка, хотя существуют алгоритмы с большей сложностью (например, сортировка слиянием).
2. @freakish ты абсолютно прав. Сложность пытается описать масштабируемость , а не скорость . Который сам по себе взрывается, если при увеличении масштаба происходит изменение O (1) на O (n).
3. Я хочу сказать, что все еще существуют некоторые ожидания относительно производительности, независимо от сложности. Особенно в этом случае. Я знаю, что нет никаких гарантий, но почти все будут использовать map вместо unordered_map без измерения, когда упорядочивание не требуется. Также о порядке: на самом деле все объекты могут быть упорядочены. В конце концов, каждый объект представлен в виде некоторого числа. Потенциально огромный, как, например, изображение, но все же число.
4. @freakish вы можете отредактировать этот ответ, если какая-либо формулировка вам не кажется правильной. Возможно, я недостаточно четко объяснил, что «упорядочение» отличается от того, возможно ли упорядочить.