Разница в производительности между map и неупорядоченной картой в c++
У меня есть простое требование, мне нужна карта типа . однако мне нужно самое быстрое теоретически возможное время поиска.
я использовал как map, так и новый предлагаемый unordered_map из tr1 я обнаружил это, по крайней мере, при разборе файла и создании карты, вставив элемент одновременно.
карта заняла всего 2 минуты, в то время как unordered_map занял 5 минут.
Как я, он будет частью кода, который будет выполняться на кластере Hadoop и будет содержать ~100 миллионов записи, мне нужно как можно меньше времени на поиск.
также еще одна полезная информация: в настоящее время вставляемые данные (ключи) представляют собой диапазон целых чисел от 1,2,... в ~10 миллионов.
Я также могу ввести пользователя, чтобы указать максимальное значение и использовать порядок, как указано выше, это значительно повлияет на мою реализацию? (я слышал, что карта основана на деревьях rb, и вставка в порядке увеличения приводит к лучшей производительности (или худшей?))
вот код
map<int,int> Label // this is being changed to unordered_map
fstream LabelFile("Labels.txt");
// Creating the map from the Label.txt
if (LabelFile.is_open())
{
while (! LabelFile.eof() )
{
getline (LabelFile,inputLine);
try
{
curnode=inputLine.substr(0,inputLine.find_first_of("t"));
nodelabel=inputLine.substr(inputLine.find_first_of("t")+1,inputLine.size()-1);
Label[atoi(curnode.c_str())]=atoi(nodelabel.c_str());
}
catch(char* strerr)
{
failed=true;
break;
}
}
LabelFile.close();
}
предварительное решение: после просмотра комментариев и ответов я считаю, что динамический массив C++ будет лучшим вариантом, так как реализация будет использовать плотные ключи. Спасибо
3 ответов
вставка для unordered_map должна быть O (1) и поиск должен быть примерно O (1), (его, по сути, хэш-таблицы).
ваши тайминги в результате пути выкл, или есть что-то неправильно С вашей реализацией или использованием unordered_map.
вам нужно предоставить дополнительную информацию и, возможно, как вы используете контейнер.
согласно разделу 6.3 из n1836 сложности для вставки/поисковая указаны:
одна проблема, которую вы должны учитывать, заключается в том, что ваша реализация может постоянно быть rehashing структура, как вы говорите, у вас есть 100mil + элементы. В этом случае при создании экземпляра контейнера, если у вас есть приблизительное представление о том, сколько "уникальный" элементы будут вставлены в контейнер, вы можете передать это в качестве параметра конструктору, и контейнер будет создан соответствующим образом с помощью таблицы ведра соответствующего размера.
дополнительное время загрузки unordered_map связано с динамическим изменением размера массива. Расписание изменения размера должно удвоить количество ячеек, когда таблица превышает коэффициент загрузки. Поэтому из пустой таблицы ожидайте o (lg n) копий всей Таблицы данных. Вы можете устранить эти дополнительные копии, предварительно определив размер хэш-таблицы. В частности,
Label.reserve(expected_number_of_entries / Label.max_load_factor());
деление на max_load_factor должно учитывать пустые ячейки, необходимые для работы хэш-таблицы.
unordered_map (по крайней мере, в большинстве реализаций) дает быстрый поиск, но относительно низкую скорость вставки по сравнению с map. Дерево обычно в лучшем случае, когда данные упорядочены случайным образом, и в худшем случае, когда данные упорядочены (вы постоянно вставляете на одном конце дерева, увеличивая частоту повторной балансировки).
учитывая, что это ~10 миллионов общих записей, вы можете просто выделить достаточно большой массив и получить очень быстрый поиск-при условии, что достаточно физических память, которая не вызывала трепки, но это не огромный объем памяти по современным стандартам.
Edit: да, вектор в основном является динамическим массивом.
Edit2: код, который вы добавили некоторые проблемы. Ваш while (! LabelFile.eof() )
разбито. Обычно вы хотите сделать что-то вроде while (LabelFile >> inputdata)
вместо. Вы также читаете данные несколько неэффективно - то, что вы, по-видимому, ожидаете, - это два числа, разделенные вкладкой. В таком случае, я бы написал цикл что-то например:
while (LabelFile >> node >> label)
Label[node] = label;