1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
||||||
1 | ||||||
Максимально эфективное бинарное чтение из файла под Windows14.12.2012, 02:50. Показов 5041. Ответов 40
Метки нет (Все метки)
Задача: максимально эфективно (быстро) читать данные из файла. Каким это будет происходить образом - в виде си функции, с++ или винапи функции не имеет значения, имеет значение лишь результат.
Как мне известно размер странички в Windows = 4Кб так что быстрее всего по идее чтение должно происходить если читать по 4 кб, но как лучше всего это сделать? Вообще в итоге я буду использоать 64битные значения после того как считаю кусок файла. Вот мой маленький набросок, который првда закончился фиаско потому что стандартная fread, как оказалось, имеет буфер под чтение меньше 4 кб так что нужно что-то другое быстрое
0
|
14.12.2012, 02:50 | |
Ответы с готовыми решениями:
40
Бинарное чтение файла Бинарное чтение файла Бинарное чтение из файла Бинарное чтение файла |
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
14.12.2012, 03:24 | 21 |
Gepar, потому что вызывать много раз операцию чтения с диска не даст никакого прироста к производительности.
Еще хорошо бы установить флаг FILE_FLAG_SEQUENTIAL_SCAN, чтобы упреждающее чтение работало лучше. Это тоже даст прирост. Добавлено через 3 минуты Gepar, и, конечно, это зависит от самого диска и и оси. Поэтому говорить, что 4к - это самый быстрый вариант - ошибка. Бери больше, и проверяй, а не верь плохим программистам.
1
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
14.12.2012, 03:24 [ТС] | 22 |
Ну ... если хапать по n мб то как тогда узнать сколько там оп свободно (чтобы при чтении не перестараться и не привести к перекачке данных в своп) ?
0
|
Форумчанин
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
|
||||||
14.12.2012, 03:38 | 24 | |||||
Gepar, я к тому сказал, что память сейчас оперативная взлетает в объемах по експоненте и беспокоится о её нехватке бесмысленно.
Вот, что я предлагаю:
Мегабайтный файл считывает за 0.004 секунды (на моем компе естественно)
0
|
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
|
|
14.12.2012, 03:48 | 25 |
можно я? какая скорость чтения с HDD и какая из RAM? Что мешает загружать в RAM по гигу или 2 и обрабатывать данные из оперативной памяти? Странный конечно подход... по 4Кб.
очевидно же.
0
|
Форумчанин
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
|
|
14.12.2012, 04:04 | 26 |
И я уж молчу про http://help.3l.com/3L/index.ht... read_h.htm из С11
0
|
836 / 343 / 67
Регистрация: 20.11.2012
Сообщений: 795
|
|
14.12.2012, 09:50 | 27 |
Самое эффективное - читать функцией ReadFile (winapi) большими блоками (>= 64 кб) с флагом FILE_FLAG_NO_BUFFERING. Это чтобы не было 100500 промежуточных буферов, как в случае с функами с и с++. Если время обработки довольно большое, то имеет смысл читать асинхронно и обрабатывать покусочно по мере поступения.
1
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
14.12.2012, 15:50 [ТС] | 28 |
WhiteP, а можно небольшой пример чтения ею бинарных данных (с правильным получением хендлера файла для этой функции), допустим для файла input.bin и буффера на 64 кб uint64_t[8192] ну и соответственно с получением информации сколько реально байт было считано (ато она я смотрю просто BOOL возвращает).
0
|
836 / 343 / 67
Регистрация: 20.11.2012
Сообщений: 795
|
||||||
14.12.2012, 17:32 | 29 | |||||
Вот как-то так. Естественно, чтобы был прирост скорости - нужно избавиться от частых вызовов тормозных потоков C++ (std::cout). Тут они только для наглядности.
1
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
||||||
17.12.2012, 01:13 [ТС] | 30 | |||||
WhiteP, не получается у меня использовать этот твой винапи вариант - почему-то WriteFile нифига не пишет и чесно признаётся что записывает каждый раз 0 байт. Какого хрена оно так ?
Вот код где я его использую, вот почему он каждый раз нифигашеньки не запсывает WriteFile этот
0
|
Модератор
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,512
|
|
17.12.2012, 01:24 | 31 |
Gepar, если тебе нужна скорость, то почему ты не задействуешь файлы проецируемые в память
грубо говоря создается копия файла в озу ты работаешь с этой копией (скорость обращения к памяти намного больше чем к винту) точно так же как с файлом потом при закрытии он скидывается на диск Добавлено через 3 минуты вот вроде неплохая статейка http://www.developing.ru/com/m... es_01.html
1
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
17.12.2012, 01:47 [ТС] | 32 |
ValeryS, я почитаю сейчас, но почему WriteFile может писать по 0 байт? Не, ну хотябы мусор там какой-то писала или ещё чего, а так файл получается в 0 байт независимо от того сколько я пытался писать ею, почему же?
*Вообще я смотрю 98% времени таки тратиться на шифрование, даже если читать по 4 кб максимум так что я думаю на чтении файла не стоит совсем сильно заострять внимание, чтение через винапи функции без буферизации должно быть достаточно, но нужно исправить эту багу с WriteFile ...
0
|
Модератор
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,512
|
|
17.12.2012, 02:22 | 33 |
не может
это значит какая то ошибка при записи вызывай GetLastError. http://vsokovikov.narod.ru/New... tefile.htm особенно посмотри раздел Замечания Добавлено через 4 минуты я кстати в коде не нашел проверки outputData файл ведь может не открыться
1
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
17.12.2012, 03:00 [ТС] | 34 |
Отдаёт код 57 после записи файла (до записи 0, те ошибка была при записи). Как определить что произошло, я уже позабывал эти винапишные штучки, там вроде что-то было для этого.
Добавлено через 44 секунды Оно бы вываливалось тогда при записи, файл открывается, я в отладчике просто смотрел что хендлер получен корректный.
0
|
256 / 46 / 4
Регистрация: 24.11.2012
Сообщений: 466
|
|
17.12.2012, 03:09 | 35 |
0
|
Модератор
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,512
|
||||||
17.12.2012, 03:14 | 36 | |||||
Примерно так
аппаратная неисправность сетевой платы а вот 0х57 уже ближе Параметр задан неверно.
0
|
836 / 343 / 67
Регистрация: 20.11.2012
Сообщений: 795
|
|
17.12.2012, 08:20 | 37 |
При записи файла, открытого с флагом FILE_FLAG_NO_BUFFERING нужно писать также как и читать - размером кратным размеру сектора (512 байт). Буфер для записи нужно выровнять (выделить память VirtualAlloc). В конце (если размер выходного файла не кратен 512) нужно вызвать SetEndOfFile. Имеет смысл формировать буфер как можно больший - т.к. чем меньше обращений к диску, тем лучше. Минимум, если размер файла позвоялет - 64Кб.
При чтении файлов с флагом FILE_FLAG_NO_BUFFERING и чтении файла через проекцию (FileMapping) - скорость первого примерно на 15%-30% выше. Писать возможно и правда лучше и удобней в проецируемый файл.
0
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
17.12.2012, 12:27 [ТС] | 38 |
Так я же так и делаю - я записываю тот буфер полностью, те 64 кб, но после той записи в DWORD writed по прежнему 0, но почему ? Или оно не скинеться на диск пока я не вызову SetEndOfFile? Но тогда где оно держит по 50 мб которые я пытался шифровать, не в оп же, я же смотрел что моё приложение так много оп не жрёт. Можешь ещё раз посмотреть на мой код, может заметишь что не так. Вроде же всё просто: считал в буфер 64 кб, записал их в файл, если считал меньше 64 кб - поредактировал последний блок и снова записал в файл. По крайней мере первые же записи что по полных 64 кб должны писаться, но я отладчиком гоняю и writed постоянно = 0 и не меняется. Столько проблем с десом этим
0
|
836 / 343 / 67
Регистрация: 20.11.2012
Сообщений: 795
|
||||||||||||||||
17.12.2012, 14:45 | 40 | |||||||||||||||
Тут надо
0
|
17.12.2012, 14:45 | |
17.12.2012, 14:45 | |
Помогаю со студенческими работами здесь
40
Бинарное чтение файла Максимально быстрое чтение очень большого файла Бинарное чтение из файла с пoмощью функции fread() Бинарное дерево поиска. Как осуществить запись в файл и чтение из файла Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |