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

Discussion in 'LANGS.C' started by varnie, Jan 20, 2009.

  1. l_inc

    l_inc New Member

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

    leo Active Member

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

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

    varnie New Member

    Blog Posts:
    0
    Joined:
    Jan 2, 2005
    Messages:
    1,785
    leo
    я вас понимаю ;)

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

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

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

    leo Active Member

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

    Pavia Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 17, 2003
    Messages:
    2,409
    Location:
    Fryazino
    varnie
    С двумя буферами идея такая. Пока твоя задача обробатывает первый, во второй жесткий читает паралельно. Но тут нужно асинхронное чтение, а о таком я в виндоусе не слышал. Если кто знает как сделать подскажите.

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

    censored New Member

    Blog Posts:
    0
    Joined:
    Jul 5, 2005
    Messages:
    1,615
    Location:
    деревня "Анонимные Прокси"
    Pavia
    Code (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

    Blog Posts:
    0
    Joined:
    Jul 10, 2006
    Messages:
    1,004
    Location:
    Abaddon
    Хэндл файла сигналит (хотя SYNCHRONIZE должен бы быть установлен автоматом..)? В каких случаях это просиходит? OVERLAPPED.hEvent не вернее?
     
  8. varnie

    varnie New Member

    Blog Posts:
    0
    Joined:
    Jan 2, 2005
    Messages:
    1,785
    что вы так прицепились к винде..
    меня винда интересует в последнюю очередь если что;) т.к. пишу под *nix-ы и тестю в первую очередь на них, а потому и пишу на C++ используя STL.
     
  9. censored

    censored New Member

    Blog Posts:
    0
    Joined:
    Jul 5, 2005
    Messages:
    1,615
    Location:
    деревня "Анонимные Прокси"
    varnie
    Вообще не понимаю о чем Ваша проблема (и почему Вы до сих пор не закрыли тему), если у вас файл меньше 1МБ.

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

    _basmp_ New Member

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

    asmfan New Member

    Blog Posts:
    0
    Joined:
    Jul 10, 2006
    Messages:
    1,004
    Location:
    Abaddon
    Добавка по коду censored
    Synchronous and Asynchronous I/O
     
  12. varnie

    varnie New Member

    Blog Posts:
    0
    Joined:
    Jan 2, 2005
    Messages:
    1,785
    asmfan
    см пост #28.
    все это интересно, но мне фиолетово на Windows и её технологии, что я уже выше подчеркнул в этом топике.
     
  13. asmfan

    asmfan New Member

    Blog Posts:
    0
    Joined:
    Jul 10, 2006
    Messages:
    1,004
    Location:
    Abaddon
    varnie топик существует вне зависимости от создателя и от его восприятия цветов. фиолетовое вам не фиолетово другим читающим его. считайте мой пост не вам, а тем, кто будет читать этот топик.
     
  14. leo

    leo Active Member

    Blog Posts:
    0
    Joined:
    Aug 4, 2004
    Messages:
    2,542
    Location:
    Russia
    asmfan
    Поскольку речь шла только о двух буферах, а не о "multiple asynchronous I/O operations", то ожидание на hFile в коде censored вполне уместно и правомерно
     
  15. asmfan

    asmfan New Member

    Blog Posts:
    0
    Joined:
    Jul 10, 2006
    Messages:
    1,004
    Location:
    Abaddon
    leo а я говорю обратное? там написано "добавка" а не опровержение) Иначе бы, после кода censored, смысла в Event'ах в OVERLAPPED струкруре совсем не было бы на первый взгляд. А так он появляется.
     
  16. leo

    leo Active Member

    Blog Posts:
    0
    Joined:
    Aug 4, 2004
    Messages:
    2,542
    Location:
    Russia
    asmfan
    Ну дык, у меня тоже не "опровержение", а уточнение ;)

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