Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ByteString to Vector conversion

Tags:

haskell

vector

I have a ByteString that is containing the representation of Floats. Each Float is represented by 3 bytes in the ByteString.

I need to do some processing on the Float values, so I would like to perform that processing on an Vector of Float values. What would be the best way to do this?

I have a function toFloat :: [Word8] -> Float that converts 3 bytes of the ByteString to a Float. So I was thinking of iterating over the ByteString in steps of 3 Bytes and converting every step to a Float for a vector.

I've looked at the library functions for Vector but I can't find anything that suits this purpose. Data.Vector.Storable.ByteString.byteStringToVector looked promising but it converts every byte (instead of every 3 bytes) and doesn't give me any control over how the conversion of ByteString to Float should happen.

like image 213
Valerie94 Avatar asked Jan 25 '17 09:01

Valerie94


2 Answers

Just use Data.Vector.generate:

V.generate (BS.length bs `div` 3) $ \i ->
  myToFloat (bs BS.! 3*i) (bs BS.! 3*i+1) (bs BS.! 3*i+2)

It'll allocate the vector all at once, and populate it. Data.ByteString.! is O(1), so this is quite efficient.

like image 134
rampion Avatar answered Nov 03 '22 00:11

rampion


Try using

splitAt :: Int -> ByteString -> (ByteString, ByteString)

to split the ByteString into two: one of exactly 3 characters, and another containing the rest of the input. You can use this to implement a recursive function that will give you all the groups of length 3 (similar to Data.List.Split.chunksOf), and then you can use unpack on each to get the [Word8] you need. Pass that through your toFloat function, and convert to a vector with Vector.fromList.

There are a number of steps there that seem like perhaps they could be expensive, but I think probably the compiler is smart enough to fuse some of them, like the unpack/fromList pair. And splitting a ByteString is O(1), so that part's not as expensive as it looks either. Seems like this ought to be as suitable an approach as any.

like image 2
amalloy Avatar answered Nov 02 '22 23:11

amalloy