Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2011, 07:08   #1
медведко
 
Регистрация: 05.11.2011
Сообщений: 7
По умолчанию Как лучше работать с несколькими миллионами строк

Здравствуйте!

Простите, если вопрос совсем глупый. Но если не трудно, направьте в нужную сторону, пожалуйста.

Итак, стоит передо мной задача (вообще, я админ) проанализировать журнал(лог) прокси сервера. При этом агрегировать похожие записи.
Т.е. допустим, в течение дня Вася ходил на Яндекс 20 раз, на Гугл - 10, на третий сайт 15 итд. Мы в итоговый массив данных будем не каждую новую строчку заносить, а добавлять к уже существующей объем скачанного.

Проблема в том, что Вась имеем несколько десятков тысяч, а строчек несколько десятков миллионов (в день). Алгоритм который работал на предыдущей работе тут не справляется

Я делал многомерный массив, 5 (пользователь, сайт, байтысюда, байтытуда, времяобработки ) на 3.000.000 элементов.

Потом построчно считываем файл журнала и на каждой строчке делаем проверку - если уже есть такой же пользователь+сайт, то добавляем к нему, если нет, заносим новый элемент.

Работает это всё нестабильно. Если количество уникальных пар пользователь+сайт меньше 500 тысяч, всё летает. Но когда их становится миллион или 2.5млн, то обрабатывается всё по 8-10 часов. А это слишком медленно.

Пробовал оптимизировать, но результат всё-равно не устраивает.
Сначала перебор записей делал по циклу for от начала до конца, когда
нашли запись, break. Потом поменял на Array.Indexof (для этого пришлось завести 4 массива, в одном одной строкой пользователь+сайт - по нему и ищет Array.Indexof, в остальных байты и время. Стало быстрее раз в 10, но всё-равно по нескольку часов думает.

Дальше уже какие-то грязные хаки пошли - маленькие сайты я добавляю под именем other, но это уже попытки уменьшить размер конечного массива, а не оптимизация.

Посоветуйте, пожалуйста, что ещё попробовать?
Чтобы был быстрый поиск строки в массиве, но при этом и возможности менять строки. То есть stringbuilder не подходит (вроде).

Dataset тоже умрет на таких объемах, по-моему, если сначала загрузить все несколько миллионов записей, а потом пытаться агрегировать. А если каждый раз select дергать, то, подозреваю, что тоже всё очень медленно будет.
медведко вне форума Ответить с цитированием
Старый 05.11.2011, 09:41   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Dictionary по ключу будет искать быстрее, чем Array.Indexof.
Для таких объемов не грех и СУБД простенькую какую-нибудь прикрутить
pu4koff вне форума Ответить с цитированием
Старый 05.11.2011, 12:42   #3
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Раздели массив на массивы. Создай на каждую букву фамилии/ника юзеров свой массив. Если Ивановых будет все равно больше 500 000 разбей на несколько и их.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 05.11.2011, 15:58   #4
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

можно использовать например SortedList (быстрый двоичный поиск)
ключом будет вася(или даже его хеш), а значением еще один словарь сайт-количество

если я правильно понял то типа такого
Код:
   
//словарь вася-сайты        
 SortedList<string, SortedList<string, int>> fooo = new ...;
           
//вытаскиваем словарь сайтов и их посещений
            SortedList<string, int> sites;  
            if (fooo.TryGetValue("вася иванов", out sites))
            {
                sites["yandex"]++;//тут тоже надо TryGetValue на случай если яндекса еще нет
            }
можно в принципе вместо внутреннего словаря и двумерный массив сделать, там наверно не так уж много сайтов

Последний раз редактировалось m0nax; 05.11.2011 в 16:06.
m0nax вне форума Ответить с цитированием
Старый 06.11.2011, 11:47   #5
медведко
 
Регистрация: 05.11.2011
Сообщений: 7
По умолчанию

Большое спасибо! Как засунуть класс в словарь не осилил (точнее, как потом с ним работать), но даже переход на словарь из двух строк дал дикий прирост скорости - теперь даже самые большие файлы обрабатываются за несколько секунд.

Благодарю!
медведко вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как вычислить кол-во пустых ячеек с несколькими условиями? Ppaa Microsoft Office Excel 6 25.07.2011 13:34
С чем лучше работать? EXMP Свободное общение 19 07.10.2010 11:15
Принтер будет работать лучше если узнает что его ждет в случае .. HellMercenariess Компьютерное железо 3 09.11.2009 09:59
С какими файлами лучше работать? blackstersl Общие вопросы Delphi 3 15.06.2009 15:12
Поиск файлов сразу с несколькими расширениями. Как??? Altera Общие вопросы Delphi 20 28.03.2008 01:43