[GHC] #2269: Word type to Double or Float conversions are slower than Int conversions

GHC trac at galois.com
Wed May 7 19:17:37 EDT 2008


#2269: Word type to Double or Float conversions are slower than Int conversions
-------------------------------------------+--------------------------------
    Reporter:  dons                        |       Owner:  dons at galois.com
        Type:  feature request             |      Status:  new            
    Priority:  normal                      |   Component:  Compiler       
     Version:  6.8.2                       |    Severity:  normal         
    Keywords:  rules, performance, double  |    Testcase:                 
Architecture:  Unknown                     |          Os:  Unknown        
-------------------------------------------+--------------------------------
 We have int2Double# and int2Float# primitives, but not equivalent ones for
 Word
 types. We may need word2Double# too, for Words* to be fully first-class
 performance-wise.

 This means we have to do extra tests in the Num instances for Word types
 to implement 'fromIntegral':

 {{{

     toInteger (W# x#)
         | i# >=# 0#             = smallInteger i#
         | otherwise             = wordToInteger x#
         where i# = word2Int# x#

 }}}

 Now, for some types, we work around this:

 {{{

 "fromIntegral/Int->Word"  fromIntegral = \(I# x#) -> W# (int2Word# x#)
 "fromIntegral/Word->Int"  fromIntegral = \(W# x#) -> I# (word2Int# x#)
 "fromIntegral/Word->Word" fromIntegral = id :: Word -> Word

 }}}

 and so on for other Word/Int types. And all is fine.

 The problem comes up for Float and Double. For Int, we can write:

 {{{

 "fromIntegral/Int->Float"   fromIntegral = int2Float
 "fromIntegral/Int->Double"  fromIntegral = int2Double

 int2Float :: Int -> Float
 int2Float   (I# x) = F# (int2Float# x)

 int2Double :: Int -> Double
 int2Double   (I# x) = D# (int2Double#   x)

 }}}

 But we can't write these rules for Word types.

 The result is a slow down on Word conversions, consider this
 program:

 {{{

 main = print . sumU
              . mapU (fromIntegral::Int->Double)
              $ enumFromToU 0 100000000

 }}}

 When in lhs is Int, we get this nice code:

 {{{

 $wfold :: Double# -> Int# -> Double#

 $wfold =
   \ (ww_s18k :: Double#) (ww1_s18o :: Int#) ->
     case ># ww1_s18o 100000000 of wild_a14T {
       False ->
         $wfold
           (+## ww_s18k (int2Double# ww1_s18o)) (+# ww1_s18o 1);
       True -> ww_s18k


 }}}

 But for Word types, we get:

 {{{

 $wfold :: Double# -> Word# -> Double#

 $wfold =
   \ (ww_s1gN :: Double#) (ww1_s1gR :: Word#) ->
     case gtWord# ww1_s1gR __word 100000000 of wild_a1do {
       False ->
         case case >=# (word2Int# ww1_s1gR) 0 of wild1_a1cS {
                False ->
                  case word2Integer# ww1_s1gR of wild11_a1d9 { (# s_a1db,
 d_a1dc #) ->
                  case {__ccall __encodeDouble Int#
                         -> ByteArray#
                         -> Int#
                         -> State# RealWorld
                         -> (# State# RealWorld, Double# #)}_a1bT
                         s_a1db d_a1dc 0 realWorld#
                  of wild12_a1bX { (# ds1_a1bZ, ds2_a1c0 #) ->
                  ds2_a1c0
                  }
                  };
                True -> int2Double# (word2Int# ww1_s1gR)
              }
         of wild1_a1bM { __DEFAULT ->
         $wfold
           (+## ww_s1gN wild1_a1bM) (plusWord# ww1_s1gR __word 1)
         };
       True -> ww_s1gN
     }

 }}}

 Which is to be expected, and the running time goes from:

 {{{

 $ time ./henning
 5.00000000067109e17
 ./henning  1.53s user 0.00s system 99% cpu 1.534 total

 }}}

 To:

 {{{

 $ time ./henning
 5.00000000067109e17
 ./henning  4.57s user 0.00s system 99% cpu 4.571 total

 }}}

 So not too bad, but still, principle of least surprise says Word and Int
 should behave the same.

 Should we have a word2Double# primop?

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2269>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the Glasgow-haskell-bugs mailing list