C # Быстрое чтение CSV из многих файлов - PullRequest
3 голосов
/ 07 января 2011

У меня есть папка с 3000 CSV-файлов размером от 1 до 100 КБ.Каждая строка в этих файлах имеет длину 43 символа.Их общий размер составляет 171 МБ.

Я пытаюсь написать программу для быстрого анализа этих файлов.

Сначала я попробовал собственную реализацию, но не был доволен ими.Результаты.Затем я нашел LumenWorks.Framework.IO.Csv в StackOverflow.У него есть смелые утверждения:

Чтобы дать больше практических чисел, с 45-МБ CSV-файлом, содержащим 145 полей и 50 000 записей, читатель обрабатывал около 30 МБ / с.В общем, прошло 1,5 секунды!Спецификации машины были P4 3,0 ГГц, 1024 МБ.

Я просто не получил ничего похожего на эти результаты.Мой процесс занимает >> 10 минут.Это потому, что это не один большой поток, а множество маленьких файлов и там есть издержки?Есть ли что-нибудь еще, что я мог бы сделать?

Я чувствую, что реализация LumenWorks была не быстрее моей собственной (я не тестировал), не говоря уже о том, что она обрабатывает кавычки, экранирование, комментарии и многострочные поля,ни один из которых мне не нужен.У меня очень обычный формат целых чисел через запятую.

Приветствия

Ответы [ 4 ]

4 голосов
/ 07 января 2011

Синтаксический анализ файла CSV связан с вводом / выводом, определяемым скоростью считывания данных с диска.Самое быстрое, что может когда-либо происходить, составляет от 50 до 60 МБ в секунду для жесткого диска на уровне потребителя.Похоже, что LumenWorks близок к этому пределу.

Такая пропускная способность будет достигнута только на чистом чистом нефрагментированном диске с файлом one .Так что головка считывателя дисков просто качает данные без необходимости много двигаться, просто след за ходом.Перемещение головы - это медленная часть, обычно около 16 миллисекунд.

При чтении 3000 файлов много движения головы.Просто открытие файла занимает около 50 миллисекунд.По крайней мере, сделайте сопоставимый тест, чтобы найти узкое место.Используйте хороший текстовый редактор и скопируйте / вставьте, чтобы сделать один гигантский файл.Сначала запустите дефрагментатор диска, Defraggler - приличный бесплатный.

Что касается улучшения кода, следите за строками.Они могут генерировать много мусора и иметь плохую локальность кэша процессора.Потоки не могут сделать код ввода / вывода быстрее.Единственным возможным улучшением является один поток, который читает файл, другой поток, который выполняет преобразование, так что чтение и преобразование перекрываются.Чтение нескольких потоков бессмысленно, они просто по очереди ждут диск.

И следят за кэшем файловой системы.Во второй раз, когда вы запустите тест для того же файла, вы получите данные из памяти, а не с диска.Это быстро, но не скажу вам, как оно будет работать в производстве.

0 голосов
/ 11 января 2011

Вы пробовали использовать LogParser?Я не уверен, что это будет происходить быстрее, но у меня был успех в некоторых сценариях.Возможно, стоит провести быструю проверку.

анализатор журнала 2.2

Где это может быть быстрее, так это чтение множества маленьких CSV, как в вашем примере.В любом случае, вы должны сравнить свой собственный код, чтобы сравнить его с люменами и logparser (и любыми другими предложениями).предположения плохие.

0 голосов
/ 07 января 2011

Попробуйте прочитать файлы в отдельных темах. Если данные необходимо читать синхронно, вы можете попытаться создать потоки для обработки открытия / закрытия файловых дескрипторов и реализовать очередь для фактического анализа данных в одном потоке

0 голосов
/ 07 января 2011

Все ли файлы "появляются" одновременно для обработки?Не могли бы вы, возможно, объединить их постепенно, поскольку они «приходят» в один файл, который обрабатывается вашей программой?10 минут - это длительное время для обработки +/- 7 МБ данных (наихудший сценарий из приведенных вами цифр)?

...