Я ожидал, что чтение файлов будет самой трудоемкой частью операции. Во многих случаях попытка прочитать несколько файлов одновременно в разных потоках скорее повредит, чем повысит производительность, но может быть полезно иметь поток, который ничего не делает, кроме чтения файлов, чтобы он мог максимально загружать диск.
Если файлы могут стать большими (что кажется вероятным) и если ни одна строка не будет превышать 32 Кбайт (8 000-32 000 символов Unicode), я бы посоветовал вам читать их кусками размером около 32 Кбайт или 64 Кбайт (не символов). Чтение файла в байтах и самостоятельное разделение на строки может быть быстрее, чем чтение его в виде строк, поскольку подразделение может происходить в другом потоке, чем при обращении к физическому диску.
Я бы предложил начать с одного потока для доступа к диску и одного потока для анализа и подсчета с очередью блокировки между ними. Поток доступа к диску должен помещать в очередь элементы данных, которые содержат массив байтов размером 32 КБ, указание количества допустимых байтов [может быть меньше 32 КБ в конце файла] и указатель того, является ли он последним запись файла. Поток синтаксического анализа должен прочитать эти элементы, разбить их на строки и обновить соответствующие счетчики.
Чтобы повысить эффективность подсчета, может быть полезно определить
class ExposedFieldHolder<T> {public T Value; }
а затем получить Dictionary<string, ExposedFieldHolder<int>>
. Придется создать новый ExposedFieldHolder<int>
для каждого слота словаря, но dictionary[elements[9]].Value++;
, вероятно, будет быстрее, чем dictionary[elements[9]]++;
, поскольку последний оператор переводится как dictionary[elements[9]] = dictionary[elements[9]]+1;
и должен искать элемент один раз при чтении и еще раз при записи].
Если необходимо выполнить синтаксический анализ и подсчет в нескольких потоках, я бы предложил, чтобы каждый поток имел свою собственную очередь, а очереди переключения потоков чтения с диска после каждого файла [все блоки файла должны обрабатываться одним и тем же потоком, поскольку текстовая строка может занимать два блока]. Кроме того, хотя можно было бы использовать ConcurrentDictionary
, было бы более эффективно, чтобы каждый поток имел свой собственный независимый Dictionary
и объединял результаты в конце.
person
supercat
schedule
26.04.2013
if (elements.Length > 6)
и переходите к доступуelements[9]
, если это правда. Так что же будет, если длина будет 7, 8 или 9? - person Matthew Watson   schedule 26.04.2013