У меня есть приблизительно 4 миллиона значений в файле, который я хочу сохранить в контейнере для выполнения вычислений.std :: unordered_map распределение, время вставки и освобождение
Ключ каждого значения состоит из 2 целых без знака Значение представляет собой структуру, содержащую 4 двойных числа.
Значения после загрузки не изменяются.
typedef pair<unsigned int, unsigned int> aa;
struct MyRecord { double a1; double a2; double a3; double a4; };
class MyRecordHash{
public:
size_t operator()(const aa &k) const{ return k.first * 10000 + k.second; }
};
struct MyRecordEquals : binary_function<const aa&, aa&, bool> {
result_type operator()(nm lhs, nm rhs) const
{
return (lhs.first == rhs.first) && (lhs.second == rhs.second);
}
};
std::unordered_map<aa,MyRecord,MyRecordHash,MyRecordEquals> MyRecords;
Я использую MyRecords.reserve (number_of_records) перед вставкой записей.
Проблема A: Хотя я вызываю резерв перед началом ввода данных, выделенной памяти недостаточно и перераспределяет все больше и больше памяти, когда она вставляет данные. Не следует ли выделить резервную память? Например, для 4-х записей он выделяет резерв 38.9Mb, а затем после вставок добавляет 256.5Mb.
Задача B: Процесс вставки довольно медленный. Я проверил коэффициент загрузки, и он никогда не увеличивается более чем на 0,5. Есть ли какие-либо предложения по проверке чего-либо еще? Я использую MyRecords.insert для вставки.
Проблема C: После завершения моих вычислений я вызываю MyRecords.clear(). Вместо того, чтобы мгновенно удалять содержимое, он начинает снимать запись по записи (приблизительно 3 Мбит/с). Если я не вызываю clear(), я получаю такое же поведение. Это нормально? Я проверил все предыдущие вопросы о stackoverflow, и единственное, что я нашел, это то, что это может быть связано с отладкой. Я использовал опцию -O3, но ничего не изменил.
Я использую компилятор MinGW-64 4.9.1.
Благодарим всех вас за это и за ваши предложения.
EDIT После предложено Комментарии и решения:
-Он, кажется, что нет никакого способа, чтобы освободить или предварительно выделить память STL для unordered_maps при использовании, кроме стандартных типов для ключа и данных, содержащихся , -Резервный метод, резервирует память только для хэшей. -Использование вектора <> с индексами, вычисленными из ключа значений, которые очень хорошо работали. Просто предопределяйте вектор, затем используя значение myvector.at() =, задайте значения. Деструктор по умолчанию освобождает вектор почти мгновенно (при этом значения 4 м занимают 2-3 секунды, а не 5 минут с unordered_map). -Использование памяти с вектором меньше, так как не сохраняется ключ -Random доступ к вектору кажется немного медленнее, хотя еще не профилировал код.
Еще раз спасибо за помощь.
Это нормально для любого контейнера для удаления объектов один за другим, он должен вызвать деструктор для каждого в любом случае. –
Пользователь должен ждать 4-5 минут для удаления! Разве нет другого способа сделать это? – Nonen
Нет, я не так, почему ты так говоришь? – Nonen