kim/leveldb-haskell — pull request #11 by NicolasT (2013-04-12 22:54:23+00:00)
Title: RFC: Zero-copy ByteString creation

Hi,

This is mainly a request-for-comments & check whether there's any interest in this, not a real pull request (for now).

Currently the library uses `packCStringLen` to turn strings returned from the LevelDB API into `ByteString`. This is an *O(n)* operation in the length of the string (it results in a `memcpy` of the string from C heap into Haskell's GC'ed heap).

This can have quite some impact when dealing with large values.

I noticed the library uses `unsafeUseAsCStringLen` to pass `ByteString` values to the LevelDB procedures, which doesn't incur any copying, so thought it'd make sense to do the reverse as well.

I think this has one drawback: the values won't show up in memory statistics & profiling, since they're outside the Haskell-managed heap.

I chose to implement the change as contained in this 69c6ff93894 instead of using `Data.ByteString.Unsafe.unsafePackCStringFinalizer`, since the latter uses `Foreign.Concurrent.newForeignPtr` to create a `ForeignPtr`, and its documentation says:

> There is no guarantee of promptness, and **in fact there is no guarantee that the finalizer will eventually run at all**.

(emphasis mine) which makes me kinda nervous. Might want to check with @dons, @dcoutts or someone else more knowledgeable than me :smile: