Обратите внимание, что ленивая строка байтов работает так, что содержимое файла не будет прочитано до тех пор, пока оно не будет «использовано», но как только оно будет прочитано, оно останется в памяти для любых последующих операций. Единственный способ, которым они будут удалены из памяти, — это сборка мусора, потому что у вашей программы больше нет доступа к ним.
Например, если вы запустите следующую программу для большого файла:
import qualified Data.ByteString.Lazy as BL
main = do
bigFile <- BL.readFile "ubuntu-14.04-desktop-amd64.iso"
print $ BL.length $ BL.filter (==0) bigFile -- takes a while
print $ BL.length $ BL.filter (==255) bigFile -- runs fast
первое вычисление фактически прочитает весь файл в память, и он будет сохранен там для второго вычисления.
Я предполагаю, что это само по себе не слишком убедительно, поскольку операционная система также будет кэшировать файл в памяти, и в конечном итоге будет трудно определить разницу во времени между чтением Haskell файла из кеша операционной системы для каждого вычисления и сохранением это в памяти для всех вычислений. Но если вы запустите профилирование кучи для этого кода, вы обнаружите, что первая операция загружает весь файл в «закрепленные» строки байтов, и это распределение остается постоянным для последующих операций.
Если вас беспокоит то, что вы хотите, чтобы весь файл читался в начале, даже если первой операции не нужно читать его весь, чтобы не было последующих задержек при чтении дополнительных частей файла, тогда ваш seq
решение на основе, вероятно, хорошо. Кроме того, вы можете прочитать весь файл как строгую строку байтов, а затем преобразовать ее с помощью fromStrict
— эта операция выполняется мгновенно и не копирует никаких данных. (В отличие от toStrict
, который является дорогостоящим и действительно копирует данные.) Таким образом, это будет работать:
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BL
main = do
-- read strict
bigFile <- BS.readFile "whatever.mov"
-- do strict and lazy operations
print $ strictOp bigFile
print $ lazyOp (BL.fromStrict bigFile)
person
K. A. Buhr
schedule
27.02.2018