Выполнение вычислений для пар подэвентов в двух больших файлах
У меня есть большие данные в двух файлах, каждый из которых содержит около двух миллионов (разных) записей. Структура файла такова, что существует номер события, и для каждого события есть несколько вложенных событий. Каждое из этих вложенных событий имеет некоторые характеристики. Например, общая структура файлов такова:
Index Event SubEvent Characteristic1 Characteristic2 ....
1 1 1 322 234
2 1 2 453 324
3 1 3 ... ...
. . . ... ...
. . . ... ...
100 1 100 ... ...
101 2 1 ... ...
102 2 2 ... ...
. . . ... ...
. . . ... ...
. . . ... ...
207 2 107 ... ...
208 3 1 ... ...
209 3 2 ... ...
и так далее, индекс достигает примерно двух миллионов.
У меня есть два файла, давайте называть их file1
а также file2
с вышеуказанной структурой. Я должен сделать некоторые вычисления, используя их характеристики для каждого события события. Вот схема того, что я придумал.
LOOP over each INDEX in file1
LOOP over each INDEX in file2
if (Event value of file1 is same as event value of file2)
/* do some computations with characteristics and store them somewhere*/
Текущая реализация, которую я написал
for (int i=0;i<nEntries_1;i++) {
file1->GetEntry(i);
for (int_t j=0; j < nEntries_2 ; j++) {
file2->GetEntry(j);
if (event1 != event2) break;
else {
/* Doing the computation with characteristics*/
}
}
}
Однако я думаю, что это неправильно. Предположим, мы находимся с индексом 209 в верхнем цикле file1. Это означает, что необходимо вычислить некоторую характеристику для события 2 в событии 3 file1
со всеми подвенчатыми событиями в 3 file2
, Однако вышеприведенный код выйдет из цикла, так как номера событий первой записи не будут совпадать.
Что может быть возможным решением. Если я просто сделаю грубую силу без if-break
Команда это занимает слишком много времени.
1 ответ
В вашем цикле вы должны сказать continue
пропустить раунд, а не ваш break
который прерывает весь цикл.
С точки зрения дизайна, ваш алгоритм крайне неэффективен, так как вы можете убедить себя, выполнив базовый анализ сложности. Соответствующая индексация ваших данных почти наверняка будет необходима.
Это именно то, для чего нужны базы данных. Я рекомендую вам установить небольшую базу данных (например, MySQL), создать две таблицы и выполнить запрос данных JOIN, который должен быть намного более эффективным, чем ваш ручной цикл.
В качестве альтернативы, если вы хотите попробовать сами, вы можете создать свою собственную микробазу в C++ с такой структурой, как std::multimap
а затем использовать euqal_range()
сделать целевое сопоставление.