#c #c 11 #vector
#c #c 11 #вектор
Вопрос:
предположим, вам нужно работать с большим количеством элементов (более 1 миллиарда), которые хранятся в vector, и в какой-то момент вы хотели бы взять все эти элементы и разделить их на группы. Чтобы быть конкретным, мы хотели бы сделать следующее:
std::vector<std::vector<int>> groups(100, std::vector<int>);
for (size_t i = 0; i < 1000000000; i) {
groups[i % 100].push_back(big_vector.push_back(i));
}
big_vector.resize(0);
big_vector.shrink_to_fit();
Однако, поскольку big_vector
он действительно массивный, довольно неудобно дублировать наши данные в памяти. Однако этого, вероятно, нельзя избежать из-за непрерывного выделения памяти векторами и невозможности изменять размер без копирования всех данных (поправьте меня, если я ошибаюсь).
Тогда возникает вопрос, какую другую структуру использовать для хранения наших больших данных? Я подумал о написании пользовательского контейнера, в котором будут храниться данные внутри std::vector<std::array<SIZE>>
, где SIZE
достаточно большой, чтобы не иметь слишком много кусков, но не настолько большой, чтобы вызвать проблемы с дублированием накладных расходов на память. Есть ли более стандартный (boost-ish) способ сделать это, или лучше всего написать пользовательский контейнер?
Для дальнейшего уточнения моих ожиданий от контейнера — было бы неплохо, если бы у него был интерфейс, похожий на vector (быстрый произвольный доступ и т.д.). Однако при необходимости я, вероятно, мог бы обойтись без произвольного доступа и только возможностью нажимать и читать вещи. В любом случае это должно быть очень быстро.
Комментарии:
1. » Однако, если необходимо, я бы, вероятно, мог обойтись без произвольного доступа и только возможностью нажимать и читать вещи». Как насчет
std::unordered_set<>
/std::unordered_multiset<>
? В C 17 они получаютextract
иmerge
функции-члены, которые делают то, что вы хотите.2. Функция, которую вы используете для разделения элементов на группы
f:i->(i0)
, т.е. с заданным индексомi
она перейдет в группуi0
. Итак, вам действительно нужны группы. Вы можете найти группу по запросу. Такжеvector::push_back()
не возвращает никакого значения, так что это неверноgroups[i % 100].push_back(big_vector.push_back(i));
3. ах, я должен был быть более конкретным об этом. I в реальном коде они разделены на группы по более сложным правилам, и необходимо, чтобы они были разделены векторами. По теме
std::unordered_set
— не приведет ли это к большим затратам памяти? Я не очень хорошо знаком с реализацией неупорядоченных множеств.4.
std::unordered_xxx<>
основаны на узлах, что имеет накладные расходы; но это также то, что позволяет им передавать элементы без их дублирования. Вам решать, стоит ли идти на компромиссы.5. Итак, разве у вас нет больших данных, уже отсортированных по группам? Или просто выполнить сортировку (big_data, group_comparator)? Это будет стоить (n * logn) времени, но только дополнительной памяти logn (с большинством
std::sort
реализаций?).