-
Notifications
You must be signed in to change notification settings - Fork 141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IO operations for ShortByteString
#547
base: master
Are you sure you want to change the base?
Conversation
One optimization is that we don't need to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although it's arguably allowed, ShortByteString
s backed by explicitly pinned ByteArray#
s can create a nasty surprise for anyone who tries to put them into a compact region. So I lean against this implementation approach for the various read operations.
unsafeHPutOff handle sbs off len = withPtr sbs $ \p -> IO.hPutBuf handle (p `plusPtr` off) len | ||
|
||
hPut :: IO.Handle -> ShortByteString -> IO () | ||
hPut h sbs = unsafeHPutOff h sbs 0 (length sbs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to re-invent the wheel here. fromShort
already basically does what the pointer-related conversions above are meant to.
hPut h sbs = unsafeHPutOff h sbs 0 (length sbs) | |
hPut h sbs = BS.hPut h (fromShort sbs) |
To keep from allocating the intermediate ByteString
, we can just move the pinnedness check from fromShort
into fromShortIO
and then use the latter.
hPut h sbs = unsafeHPutOff h sbs 0 (length sbs) | |
hPut h sbs = fromShortIO sbs >>= BS.hPut h |
I don't see any other implementation approach that is efficient. If people want to unpin it, they can do it themselves. We can make sure to document that the functions will return pinned I don't think that the use case of compact regions warrants sacrificing the performance for the most common use case. |
Well...
Come to think of it, the whole "was this |
What do you mean by this? |
@clyring @oberblastmeister is there any way forward with this PR? It would be great to get something like this for the sake of haskell/text#503. |
I'm not sure. There is definitely some improvement possible without breaking anything, as mentioned in my last comment:
But I think we need more progress on GHC's end if we want to avoid copying elsewhere without introducing an obscure footgun about compaction. (And unfortunately, getting GHC to that point is a lot of work, and probably needs multiple proposals. I don't think it's happening particularly soon.) |
Addresses #540. The functions mostly make use of
unsafePlainToShortIO
which performs a zero cost conversion between aPlainForeignPtr
andShortByteString
, using some unsafe stuff that I hope is correct. For things likehPut
, we make sure topin
theByteArray
before giving it tohPutBuf
. Hopefully mykeepAlive#
usage is correct, which I copied fromwithForeignPtr
. These operations should be useful for implementing utf8 IO intext
, solving thereadFile
problem with good performance.