Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to `read` lazily?

Tags:

haskell

I have probably just spend a day of computation time in vain :)

The problem is that I (naively) wrote about 3.5GB of (compressed) [(Text, HashMap Text Int)] data to a file and at that point my program crashed. Of course there is no final ] at the end of the data and the sheer size of it makes editing it by hand impossible.

The data was formatted via Prelude.show and just at this point I realize that Prelude.read will need to the whole dataset into memory (impossible) before any data is returned.

Now ... is there a way to recover the data without resorting to write a parser manually?

Update 1

main = do
  s <- getContents
  let hs = read s :: [(String, M.Map String Integer)]
  print $ head hs

This I tried ... but it just keeps consuming more memory until it gets killed by the OS.

like image 695
fho Avatar asked Jul 03 '14 16:07

fho


People also ask

What is lazy read?

The idea of lazy reading is that instead of reading all the data in a CSV file up front you instead read it only on-demand. For example the following code reads the column headers, filters based on column hp then computes the mean of the filtered column mpg .

Is lazy loading good?

Today, lazy loading is widely used in web applications to improve application performance. It helps developers reduce loading times, optimize data usage and improve the user experience. However, overusing lazy loading can affect the application performance negatively.

What is eager and lazy loading?

While lazy loading delays the initialization of a resource, eager loading initializes or loads a resource as soon as the code is executed. Eager loading also involves pre-loading related entities referenced by a resource.

What is lazy loading of data?

Lazy loading is a strategy to identify resources as non-blocking (non-critical) and load these only when needed. It's a way to shorten the length of the critical rendering path, which translates into reduced page load times.


1 Answers

Sort of. You will still be writing a parser manually... but it is a very short and very easy-to-write parser, because almost all of it will ship out to read. The idea is this: read is strict, but reads, when working on a single element, is lazyish. So we just need to strip out the bits that reads isn't expecting when working on a single element. Here's an example to get you started:

> let s = "[3,4,5," ++ undefined
> reads (drop 1 s) :: [(Int, String)]
[(3,",4,5,*** Exception: Prelude.undefined

I included the undefined at the end as evidence that it is in fact not reading the entire String before producing the parsed 3 at the head of the list.

like image 75
Daniel Wagner Avatar answered Sep 20 '22 02:09

Daniel Wagner