unix
unix copied to clipboard
Use unsafeDupablePerformIO instead of unsafePerformIO in struct field reads?
As it unsafePerformIO is much slower and forces the program to run single-threadedly while providing no benefits.
Can you point at a few salient examples?
As it unsafePerformIO is much slower and forces the program to run single-threadedly while providing no benefits.
It does provide benefits. bracketed functions inside unsafeDupablePerformIO
are broken: https://hackage.haskell.org/package/base-4.16.2.0/docs/System-IO-Unsafe.html#v:unsafeDupablePerformIO
So we'd need to know exactly what you mean to judge whether that's a good idea.
https://github.com/haskell/unix/blob/b315336f219c9afdf1586bb21c90ee76f59271d1/System/Posix/Files/Common.hsc all of these for example
Indeed those particular examples are IIRC safe for unsafeDupablePerformIO
or even something more aggressive, like similar read-only code in bytestring
via accursedUnutterablePerformIO
:
{-# INLINE accursedUnutterablePerformIO #-}
accursedUnutterablePerformIO :: IO a -> a
accursedUnutterablePerformIO (IO m) = case m realWorld# of (# _, r #) -> r
The difference with unsafeDupablePerformIO
is:
unsafeDupablePerformIO (IO m) = case runRW# m of (# _, a #) -> lazy a
Which takes a few extra precautions against some compiler optimisations, but ultimately (late) inlines to similar code. My sense is that if the bytestring
code can read foreign pointer payloads with accursedUnutterablePerformIO
, the same should be true here. For example in ByteString.head
, we have: accursedUnutterablePerformIO $ unsafeWithForeignPtr x $ \p -> peek p
. Which by the way also uses unsafeWithForeignPtr
.