arrays - IOUArray to ByteSring, as quickly as possible -
i need mutate elements in fixed size array of word8
quickly. purpose using iouarray
. need send array on websocket connection. function sendbinarydata
websockets package requires bytestring
. need convert 1 representation other. using function currently:
arraytobs :: iouarray int word8 -> io (bs.bytestring) arraytobs = (fmap bs.pack) . getelems
this function converts elements of array [word8]
before packing list bytestring, , profiling can see quite slow. wondering if there way speed function, or possibly send array on websocket connection directly?
the array using is:
size = 1000; numbytes = size * size * 4 newbuffer :: io (iouarray int word8) newbuffer = newarray (0, numbytes) 200 :: io (iouarray int word8)
and except performance report:
cost centre module src %time %alloc arraytobs lib src/lib.hs:28:1-37 88.1 99.0 newbuffer lib src/lib.hs:(23,1)-(25,12) 9.9 0.8
ideally arraytobs
faster creating array. if change size
100:
cost centre module src %time %alloc arraytobs lib src/lib.hs:21:1-37 100.0 86.1 mkencodetable.table data.bytestring.base64.internal data/bytestring/base64/internal.hs:105:5-75 0.0 8.0 mkencodetable.ix data.bytestring.base64.internal data/bytestring/base64/internal.hs:104:5-43 0.0 1.1
disclaimer: i'm not familiar these low level primitives might unsafe in cases.
you @ least need copy data on once since, @user2407038 remarks, underlying data stored in iouarray
unpinned array, can't count on ghc not moving array around. reverse direction (bytestring
ioarray
) possible without copy.
{-# language unboxedtuples, magichash #-} import data.bytestring.internal (bytestring(..)) import data.array.io.internals (iouarray(..)) import data.array.base (stuarray(..)) import foreign.foreignptr (mallocforeignptrbytes, withforeignptr) import ghc.io (io(..)) import ghc.exts (copymutablebytearraytoaddr#, ptr(..), int(..)) arraytobs :: iouarray int word8 -> io bytestring arraytobs (iouarray (stuarray _ _ n@(i# n') mutbytearr)) = bytes <- mallocforeignptrbytes n withforeignptr bytes $ \(ptr addr) -> io $ \state -> (# copymutablebytearraytoaddr# mutbytearr 0# addr n' state, () #) pure (ps bytes 0 n)
here test of working (remember ascii code 'a'
65
):
ghci> iou <- newlistarray (-2,9) [65,67..] :: io (iouarray int word8) ghci> arraytobs iou "acegikmoqsuw"
Comments
Post a Comment