парсинг файла: как быстрее?

Тема в разделе "LANGS.C", создана пользователем varnie, 20 янв 2009.

  1. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    varnie
    В общем лично я бы проводил чтение по 1 - 4 мегабайт, распараллеливая его с парсингом считанных данных. Хотя в принципе при выборе размеров кусков можно начинать с 64 КБ (и далее кратно этому значению). В любом случае при распараллеливании потери времени на считывание данных возникнут только при первом чтении, т.к. вряд ли парсинг будет занимать меньше времени, чем считывание.
     
  2. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    varnie
    Каков вопрос - таков и ответ ;) То вообще беспочвенные рассуждения, то конкретная цифра "до неск килобайт (теоретически)", а теперь оказывается "теоретически может быть и неск. сотен килобайт".
    Ответ - пофиг, сколько там теоретически в максимуме может оказаться - нужно ориентироваться на некое разумное среднее и иметь в виду разумный максимум. Но в любом случае, если речь идет о десятках-сотнях килобайт, то нужно читать все целиком и не морочить себе и другим голову ;)
    PS: Кстати, помимо чистого С++ не мешало бы и с физикой дружить ;). На одно только позиционирование головки HDD требуется десяток миллисекунд, а с учетом путешествия твоего запроса на чтение по недрам ОС и железу и того больше. В то же время скорость последовательного чтения современных HDD составляет 50-80 Мб/с и твои несколько сотен Кб прочитаются за единицы миллисекунд - какое тут нафиг распараллеливание, асинхронное чтение или тем более потоки ?!

    l_inc
    Если только с FILE_FLAG_NO_BUFERING, т.к. при кэшируемом чтении винда при размерах блока более 64К "дуреет", т.к. не знает как ей быстренько "впихнуть" твои мегабайты в свой файловый маппинг блоками по 256К :)
     
  3. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    leo
    я вас понимаю ;)

    но меня зацепила выдержка, которую я привел в своем посте #13, и заставила задуматься:

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

    учитывая то что
    leo:
    выходит, что все это нафик не надо. считать за раз и дело с концом.
    так где же истина? ^_^
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    varnie
    Во-первых, советуют читать блочно по сравнению с дебильным вариантом
    т.е. посимвольного чтения с помощью АПИ ReadFile(hFile,buf,1,..), при котором львиная доля времени уходит на бестолковое переключение юзермод-кернелмод и обратно.
    Во-вторых, CRT-шные fgetc\getc и так читают средствами ОС достаточно большие блоки данных (у мелкософта по умолчанию 4К) в буфер потока и затем выдают юзеру по 1 символу уже из буфера. Причем размер буфера можно увеличить вплоть до считывания всего файла целиком вызовом setvbuf.
    Ну, и в третьих, опять же речь идет об общей схеме обработки без привязки к конкретным размерам - ты же не собираешься сотню-другую байт читать блоками ?! А для современных дисков и ОС также и файлы в единицы-сотни Кб тоже не имеет смысла дробить на блоки, т.к. за счет увеличения плотности записи и буферизации данных в контроллерах, скорости чтения и передачи данных существенно выросли, а вот время доступа к произвольному сектору осталось практически на том же уровне. Также и у современных ОЗУ на DDR\DDR2\DDR3 скорость пакетной передачи возросла до немыслимых ранее гиговых величин, а время случайного доступа (в ширпотребном майнстриме) изменилось незначительно и бултыхается на уровне сотни-другой мегагерц.
    Вывод- прикручивать асинхронное чтение и работу с двумя буферами имеет смысл только для достаточно больших многометровых файлов, а для единиц-сотен Кб - игра не стоит свеч.
    PS: Впрочем если хочешь поэкспериментировать, то пожалуйста - вот только не знаю, поддерживает ли С++ overlapped-чтение без привязки к ОС, т.к. с многопоточностью тут врядли что выиграешь
     
  5. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    varnie
    С двумя буферами идея такая. Пока твоя задача обробатывает первый, во второй жесткий читает паралельно. Но тут нужно асинхронное чтение, а о таком я в виндоусе не слышал. Если кто знает как сделать подскажите.

    Но в любом случии что-бы чтение было оптимальным нужно делать чтение блоками. Оптимальный размер блока варьируется начиная от 64 кб так до 1мб.
     
  6. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    Pavia
    Код (Text):
    1. HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);
    2. BYTE *pBuf = new BYTE[1024 * 1024];
    3. OVERLAPPED o = { 0 };
    4. o.Offset = 1024 * 1024; // читаем файл со 2го мегабайта
    5. BOOL bResult = ReadFile(hFile, pBuf, 1024 * 1024, NULL, &o);
    6. DWORD dwError = GetLastError();
    7. if (!bResult && (dwError == ERROR_IO_PENDING)) {
    8.   // ждем завершения I/O
    9.   bResult = WaitForSingleObject(hFile, INFINITE);
    10. }
    11. ...
     
  7. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Хэндл файла сигналит (хотя SYNCHRONIZE должен бы быть установлен автоматом..)? В каких случаях это просиходит? OVERLAPPED.hEvent не вернее?
     
  8. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    что вы так прицепились к винде..
    меня винда интересует в последнюю очередь если что;) т.к. пишу под *nix-ы и тестю в первую очередь на них, а потому и пишу на C++ используя STL.
     
  9. censored

    censored New Member

    Публикаций:
    0
    Регистрация:
    5 июл 2005
    Сообщения:
    1.615
    Адрес:
    деревня "Анонимные Прокси"
    varnie
    Вообще не понимаю о чем Ваша проблема (и почему Вы до сих пор не закрыли тему), если у вас файл меньше 1МБ.

    asmfan
    Дж. Рихтер, Дж. Кларк. Программирование серверных приложений для Windows 2000:
     
  10. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    varnie
    истина в том, что для двух байт или сотни килобайт это без разницы. А вот начиная с десятка мегабайт начинает сказываться фрагментация, параллельно-конкуририрующее чтение/запись (в своп напр) итд. схема которую я привел выше целиком и полностью выдрана из описалова работы буферов директ соунда. Ну и потом, как бы быстро не читал винт, требования могут быть еще выше. (не этот случай. 10 байт это не серьезно)
     
  11. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Добавка по коду censored
    Synchronous and Asynchronous I/O
     
  12. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    asmfan
    см пост #28.
    все это интересно, но мне фиолетово на Windows и её технологии, что я уже выше подчеркнул в этом топике.
     
  13. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    varnie топик существует вне зависимости от создателя и от его восприятия цветов. фиолетовое вам не фиолетово другим читающим его. считайте мой пост не вам, а тем, кто будет читать этот топик.
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    asmfan
    Поскольку речь шла только о двух буферах, а не о "multiple asynchronous I/O operations", то ожидание на hFile в коде censored вполне уместно и правомерно
     
  15. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    leo а я говорю обратное? там написано "добавка" а не опровержение) Иначе бы, после кода censored, смысла в Event'ах в OVERLAPPED струкруре совсем не было бы на первый взгляд. А так он появляется.
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    asmfan
    Ну дык, у меня тоже не "опровержение", а уточнение ;)

    PS: Если уж "придираться", то к WaitForSingleObject и многоточию, т.к. по смыслу нужно бы запустить чтение нового блока и заняться обработкой предыдущего (многоточие), а по завершении обработки проверить\дождаться готовности нового блока по GetOverlappedResult