Хотя вы можете использовать второй поток для анализа данных после их чтения, вы, вероятно, не получите при этом огромной суммы. Попытка использовать более одного потока для чтения данных почти наверняка снизит скорость, а не улучшит ее. Использование нескольких потоков для обработки данных бессмысленно — обработка будет во много раз быстрее, чем чтение, поэтому даже с одним дополнительным потоком ограничением будет скорость диска.
Один (возможный) способ получить значительную скорость - это обойти обычные потоки ввода-вывода - хотя некоторые из них почти так же быстры, как использование C FILE *, я не знаю ничего, что действительно быстрее, а некоторые значительно медленнее. Если вы используете это в системе (например, Windows), которая имеет модель ввода-вывода, заметно отличающуюся от C, вы можете получить значительно больше, если немного позаботитесь.
Проблема довольно проста: файл, который вы читаете, (потенциально) больше доступного места в кэше, но вы ничего не выиграете от кэширования, потому что вы не собираетесь снова перечитывать куски файла ( по крайней мере, если вы делаете вещи разумно). Таким образом, вы хотите, чтобы система обходила любое кэширование и просто переносила данные как можно напрямую с диска в вашу память, где вы можете их обработать. В Unix-подобной системе это, вероятно, open()
и read()
(и вы не получите многого). В Windows это CreateFile
и ReadFile
, передача флага FILE_FLAG_NO_BUFFERING
в CreateFile
-- и это, вероятно, примерно удвоит вашу скорость, если вы все сделаете правильно.
Вы также получили несколько ответов, пропагандирующих выполнение обработки с использованием различных параллельных конструкций. Я думаю, что они в корне ошибочны. Если вы не сделаете что-нибудь ужасно глупое, время подсчета слов в файле будет всего на несколько миллисекунд больше, чем простое чтение файла.
Я бы использовал структуру, состоящую из двух буферов, скажем, по мегабайту каждый. Чтение данных в один буфер. Передайте этот буфер потоку подсчета, чтобы подсчитать слова в этом буфере. Пока это происходит, прочитайте данные во второй буфер. Когда это будет сделано, в основном поменяйте местами буферы и продолжите. Существует небольшая дополнительная обработка, которую вам нужно будет выполнить при обмене буферами, чтобы иметь дело со словом, которое может пересечь границу из одного буфера в другой, но это довольно тривиально (в основном, если буфер не заканчивается белым пространство, вы все еще в слове, когда вы начинаете работать со следующим буфером данных).
Пока вы уверены, что он будет использоваться только на многопроцессорной (многоядерной) машине, использование реальных потоков вполне допустимо. Если есть шанс, что это когда-либо будет сделано на одноядерной машине, вам будет лучше использовать вместо этого один поток с перекрывающимся вводом-выводом.
person
Jerry Coffin
schedule
26.10.2009