прив~ интересуют наибыстрейшие пути обработки данных, реализованные на плюсах (полагаю, с подгрузкой следующего блока данных по запросу). что-то близкое к работе парсера любого компилера/интерпретатора. т.е. исходный файл считывается в память не сразу, а последовательно, по кускам, парсится, если все ок, то запрашивается сл порция. кто сталкивалса с подобным? или же не заморачиваться, и целиком считать файл в std::vector<std::string> и работать с ним, без всяких подкачек? в инете нарыл какую-то простенькую схему "double buffer scheme", где используются 2 буффера, и по прочтению первого, переключаемся на второй, а первый подгружаем заново. вот и озадачилса, как все же поступить? приветствуются любые адекватные предложения. спасибо.
или же здесь действует какой-то интеллектуальный принцип: скажем, если файл относительно небольшой, то считываем сразу в буфер (контейнер) в ином случае устраиваем пляски с переключением буферов или что-то тому подобное (описано выше)?
Я думаю, что размер буфера лучше определяться по тому - как часто парсеру приходится менять алгоритм своей работы (если часто, то и буфер должен быть меньше). То есть - чем "проще" текст, чем большие порции надо читать. Хотя подожди, вот скоро сюда еще кто-то придет и напишет - что все это бред и предложит собственный вариант. Я не понимаю - зачем там два буфера и... это как? 2 потока что ли (один - заполняет буфер, а из другого читаются данные)? Поясни. По поводу использования неск. буферов есть только такая идея - можно иметь несколько буферов одинакового размера и читать / писать из них данные в одном цикле (счетчик цикла будет для всех буферов общим). Так мы только сэкономим на циклах (зато наверняка проиграем в объеме алгоритма). Это хорошая идея! Можно в одном цикле читать данные из 2-го буфера.
лучше всего использовать кольцевой буфер разделенный на 3-4 сектора и работа в 2 потока. после распарсивания очередного сектора один из потоков устанавливает соответствующее событие, другой из потоков после считывания в очередной сектор устанавливает тоже соответствующее событие. Само собой перед переходом в очередной сектор ожидается снова соответствующее событие из другого потока. Так если секторов 4, событий - 8. АДД точку поставил
Partner проще, но не быстрее, тк читаться с диска начнется только после обращения, а сама читка - медленная операция
скажем, каким образом разные парсеры определяют для себя, как подгружать данные: сразу же целиком за раз, или же по кускам по мере процесса парсинга, или еще как... решение влоб -- считать всё за раз в std::vector<std::string> и не мучиться. но я хочу рассмотреть и другие подходы (полагаю, более грамотные).
varnie Как вариант использовать предложенный_basmp_-ом способ + OpenMP, который кроссплатформен и поддерживается многими компиляторами.
varnie Зависит от размера входных данных. Считать за раз хорошая идея. Вот если тебе надо распаристь большой файл. Первый вопрос зачем это надо?
varnie при достаточно длинных файлах, решение в лоб будет тормозить, тк вы сперва дождетесь полного считывания через 2 буфера, а потом еще и парсить будете
Pavia предположим, есть некая модель парсинга входных статистических данных. а входной файл с данными может быть от пары десятков байт по размеру до неск килобайт (теоретически).
_basmp_ под решением в лоб имелось ввиду полное единократное считывание данных в один буфер. решение же с использованием двухбуферную схему подразумевает под собою:
varnie когда я говорил о полном чтении через 2 буфера имелось ввиду, что сперва полностью читается в кэш, а затем гонится в ваш буфер, а прога все это время ждет. Но если пару байт-пару килобайт, то без разницы
STL наверное не лучший подход. Этот самый <vector> of <string>-s как раз может замедлить ухищрения с буферами. Если речь идёт о файлах в несколько килобайт - тогда файл целиком в память через malloc() и затем разбирать символ за символом. Если файлы больше, скажем двух мегабайт - тогда можно выбрать буфер подходящего размера - например 512 Кб с подкачкой.
Вообще-то оптимальный метод чтения для однопоточной модели зависит от типа данных файла, т.к. парсер обрабатывает конкретные блоки кода, то и читаем блоками кода или кратно им. Тип файла Метод чтения Текстовые файлы Строками Базы данных Полями Двоичный (формат данных не знаем, Блоками, размером не меньшим, чем max но будем распознавать) размер формата данных
Vam благодарю за ответ. т.е. в моем случае выходит стОит читать файл по-строчно? так почему же выше идею о первоначальном считывании всего файла в std::vector<std::string> > забраковали? IMHO, в любом случае имеет смысл сразу же считать весь файл в буфер (контейнер).
varnie ЛОЛ. При таких мизерных размерах вообще непонятно, откуда вопрос возник. Одно дело, если бы размеры файла гигабайтами - десятками гигабайт исчислялись, а тут всего несколько секторов в худшем случае. ИМХО однозначно всё сразу считывать.
varnie "Идею о первоначальном считывании всего файла" никто не забраковывал, т.к. все дело в размере файла. При обычном буферированном чтении (без флага FILE_FLAG_NO_BUFERING) винда читает файлы в системный кэш страницами по 4К да еще с упреждением до 64К. Поэтому для файлов в несколько Кб остается только скопировать их целиком в свой буфер, чтобы минимизировать потери на лишние обращения к ядру (ReadFile). А построчное чтение это вообще "казуистика", + в данном случае еще и "антиоптимизация", т.к. для разбивки на строки CRT по любому сначала читает данные из сис.кэша в некий внутренний буфер, ищет в нем разделители строк и затем копирует символы в твой буфер строки - налицо куча ненужных промежуточных действий, которые можно совместить с парсингом
leo спасибо за пост. но, я так и не увидел внятного ответа касаемо сабжа. (может, плохо понимаю размытые фразы). l_inc в том то и дело, что размер входных данных варьируется. теоретически может быть и неск. сотен килобайт.