Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make fast big circular buffer arrays for stream recording in Haskell?

Tags:

haskell

I'm considering converting a C# app to Haskell as my first "real" Haskell project. However I want to make sure it's a project that makes sense. The app collects data packets from ~15 serial streams that come at around 1 kHz, loads those values into the corresponding circular buffers on my "context" object, each with ~25000 elements, and then at 60 Hz sends those arrays out to OpenGL for waveform display. (Thus it has to be stored as an array, or at least converted to an array every 16 ms). There are also about 70 fields on my context object that I only maintain the current (latest) value, not the stream waveform.

There are several aspects of this project that map well to Haskell, but the thing I worry about is the performance. If for each new datapoint in any of the streams, I'm having to clone the entire context object with 70 fields and 15 25000-element arrays, obviously there's going to be performance issues.

Would I get around this by putting everything in the IO-monad? But then that seems to somewhat defeat the purpose of using Haskell, right? Also all my code in C# is event-driven; is there an idiom for that in Haskell? It seems like adding a listener creates a "side effect" and I'm not sure how exactly that would be done.

like image 502
lobsterism Avatar asked Jan 31 '12 00:01

lobsterism


1 Answers

Look at this link, under the section "The ST monad":

http://book.realworldhaskell.org/read/advanced-library-design-building-a-bloom-filter.html

Back in the section called “Modifying array elements”, we mentioned that modifying an immutable array is prohibitively expensive, as it requires copying the entire array. Using a UArray does not change this, so what can we do to reduce the cost to bearable levels?

In an imperative language, we would simply modify the elements of the array in place; this will be our approach in Haskell, too.

Haskell provides a special monad, named ST, which lets us work safely with mutable state. Compared to the State monad, it has some powerful added capabilities.

We can thaw an immutable array to give a mutable array; modify the mutable array in place; and freeze a new immutable array when we are done.

...

The IO monad also provides these capabilities. The major difference between the two is that the ST monad is intentionally designed so that we can escape from it back into pure Haskell code.

So should be possible to modify in-place, and it won't defeat the purpose of using Haskell after all.

like image 196
Dax Fohl Avatar answered Nov 07 '22 22:11

Dax Fohl