Чтобы ответить на ваш вопрос напрямую: вы можете полностью загрузить файл в поток памяти, а затем повторно прочитать из этого потока с помощью CsvReader. Точно так же вы можете создать больший буфер чтения для вашего файлового потока, например, 15 МБ, который будет считывать весь файл в буфер за одно обращение. Я сомневаюсь, что любой из них действительно улучшит производительность для файлов размером 10 МБ.
Найдите свое реальное узкое место в производительности: время на чтение содержимого файла с диска, время на разбор CSV в поля или время на обработку записи? Файл размером 10 МБ выглядит очень маленьким. Я обрабатываю наборы CSV-файлов размером более 250 МБ с помощью специальной программы чтения CSV без каких-либо жалоб.
Если обработка является узким местом, и у вас есть несколько доступных потоков, а формат вашего CSV-файла не должен поддерживать экранированные разрывы строк, вы можете прочитать весь файл в список строк (System.IO.File.ReadAllLines / .ReadLines) и анализировать каждую строку, используя другую задачу. Например:
System.IO.File.ReadLines()
.Skip(1) // header line. Assume trusted to be correct.
.AsParallel()
.Select(ParseRecord) // RecordClass ParseRecord(string line)
.ForAll(ProcessRecord); // void ProcessRecord(RecordClass)
Если у вас есть много файлов для анализа, вы можете обрабатывать каждый файл в отдельной задаче и использовать асинхронные методы, чтобы максимизировать пропускную способность. Если все они поступают с одного и того же физического диска, то ваш пробег будет отличаться и может даже ухудшиться, чем однопоточный подход.
Более продвинутый:
Если вы знаете, что ваши файлы содержат только 8-битные символы, вы можете работать с массивами байтов и пропустить накладные расходы StreamReader для преобразования байтов в символы. Таким образом, вы можете прочитать весь файл в массив байтов за один вызов и сканировать разрывы строк, предполагая, что не требуется поддержка экранирования разрывов строк. В этом случае поиск разрывов строк может выполняться несколькими потоками, каждый из которых просматривает часть массива байтов.
Если вам не нужно поддерживать экранирование полей (a, "b, c", d), вы можете написать более быстрый синтаксический анализатор, просто ищущий разделители полей (обычно запятую). Вы также можете разделить синтаксический анализ разграничения полей и синтаксический анализ содержимого поля на потоки, если это является узким местом, хотя локальность доступа к памяти может свести на нет все преимущества.
При определенных обстоятельствах вам может не понадобиться анализировать поля в промежуточные структуры данных (например, двойные числа, строки) и вы можете обрабатывать непосредственно ссылки на начало/конец полей и избавить себя от создания промежуточной структуры данных.
person
typpo
schedule
08.08.2017