
#8638: Optimize by demoting "denormalized" Integers (i.e. J# -> S#) --------------------------------------------+------------------------------ Reporter: hvr | Owner: hvr Type: feature request | Status: new Priority: normal | Milestone: 7.8.1 Component: libraries (other) | Version: 7.7 Resolution: | Keywords: integer- Operating System: Unknown/Multiple | gmp Type of failure: Runtime performance bug | Architecture: Test Case: | Unknown/Multiple Blocking: | Difficulty: Unknown | Blocked By: | Related Tickets: --------------------------------------------+------------------------------ Description changed by hvr: Old description:
In the course of a recent [discussion on reddit](http://www.reddit.com/r/haskell/comments/1twtvm/the_problem_with_integer/) it was highlighted, that `integer-gmp` doesn't try to demote `J#` to the more efficient `S#` if even though they would fit.
The attached proof-of-concept patch introduces a "smart" `J#` constructor which constructs a `S#` instead if possible:
{{{ #!hs -- | Demote 'J#' to 'S#' if possible. See also 'smartJ#'. toSmall :: Integer -> Integer toSmall i@(S# _) = i toSmall (J# 0# _) = S# 0# toSmall (J# 1# mb#) | isTrue# (v ># 0#) = S# v where v = indexIntArray# mb# 0# toSmall (J# -1# mb#) | isTrue# (v <# 0#) = S# v where v = negateInt# (indexIntArray# mb# 0#) toSmall i = i
-- | Smart 'J#' constructor which tries to construct 'S#' if possible smartJ# :: Int# -> ByteArray# -> Integer smartJ# s# mb# = toSmall (J# s# mb#) }}}
And replaces a couple of `J#`-constructions which are likely to produce a `S#`-fitting `Integer`. A `nofib` comparison for vanilla GHC HEAD vs patched GHC HEAD is attached for further discussion.
New description: In the course of a recent [[http://www.reddit.com/r/haskell/comments/1twtvm/the_problem_with_integer/|recent reddit discussion]] it was highlighted, that `integer-gmp` doesn't try to demote `J#` result-values to the more efficient `S#` even though they would fit into a machine word. The attached proof-of-concept patch introduces a "smart" `J#` constructor which constructs a `S#` value instead (if possible): {{{ #!hs -- | Demote 'J#' to 'S#' if possible. See also 'smartJ#'. toSmall :: Integer -> Integer toSmall i@(S# _) = i toSmall (J# 0# _) = S# 0# toSmall (J# 1# mb#) | isTrue# (v ># 0#) = S# v where v = indexIntArray# mb# 0# toSmall (J# -1# mb#) | isTrue# (v <# 0#) = S# v where v = negateInt# (indexIntArray# mb# 0#) toSmall i = i -- | Smart 'J#' constructor which tries to construct 'S#' if possible smartJ# :: Int# -> ByteArray# -> Integer smartJ# s# mb# = toSmall (J# s# mb#) }}} The patch replaces a couple of `J#`-invocations which are likely to produce a `S#`-fitting `Integer`. A `nofib` comparison for vanilla GHC HEAD vs. patched GHC HEAD is attached for further discussion. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8638#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler