Reputation: 6039
There is unboxed types GHC for Int, Float, etc. I know about code built on them is running with less overhead, but I don't see a way how to input and output data to/from a function based on unboxed Int i.e.
GHC.Exts defines functions (+#) and (*#), but I cannot find function boxing/unboxy
readInt:: String -> Int#
showInt:: Int# -> String
boxInt :: Int# -> Int
unboxInt :: Int -> Int#
instance Show Int# and instance Read Int# cannot exist because show and read polymorphic.
Without these function how could I integrated optimized code block on unboxed types with the rest of application?
Upvotes: 3
Views: 795
Reputation: 120711
I know about code built on them is running with less overhead
Though this is true in a sense, it's nothing you should normally worry about. GHC tries very hard to optimise away the boxes of built-in types, and I'd expect that it manages to do it well in most cases where you could do that manually as well.
In practice, what you should be more careful about is to ensure
Int
or Float
type for which it knows the unboxed form. In particular, this does not work for polymorphic functions (polymorphism generally relies on the boxes, like it does in OO languages).SPECIALIZE
annotation and/or rewrite rules.And of course profile your code.
Only if you're really sure you want it (e.g. to ensure that the boxes won't re-appear when a new GHC that optimises differently), or maybe if you'd like to get SIMD instructions in, should you actually do manual accesses to unboxed primitive types.
Upvotes: 5
Reputation: 29193
Int
, Float
, etc. are just data
types in GHC:
data Int = I# Int#
data Float = F# Float#
-- etc.
The constructors are only exported by GHC.Exts
. Import it and use the constructors to convert:
{-# LANGUAGE MagicHash #-}
import GHC.Exts
main = do I# x <- readLn
I# y <- readLn
print (I# (x +# y))
Upvotes: 5