Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#2251 closed bug (fixed)

Missing conversion rules for realToFrac causing slowdowns in Int->Double conversions

Reported by: dons Owned by: dons
Priority: normal Milestone:
Component: Runtime System Version: 6.8.2
Keywords: floating point, performance Cc: dons@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


GHC.Real and GHC.Float currently have:

-- | general coercion from integral types
fromIntegral :: (Integral a, Num b) => a -> b
fromIntegral = fromInteger . toInteger

"fromIntegral/Int->Int" fromIntegral = id :: Int -> Int

-- | general coercion to fractional types
realToFrac :: (Real a, Fractional b) => a -> b
realToFrac = fromRational . toRational

"realToFrac/Int->Int" realToFrac = id :: Int -> Int

But these avoid some primops that can make these conversions more efficient.

"realToFrac/Int->Double" realToFrac = i2d :: Int -> Double

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

A rule to use the in2Double# primop over realToFrac directly, improves the running time of this program:

import Data.Array.Parallel.Unlifted
main = do
    let c = replicateU n (2::Double)
        a = mapU realToFrac (enumFromToU 0 (n-1) ) :: UArr Double
    print (sumU (zipWithU (*) c a))

From 113 seconds, to 0.194s! A massive speedup.

We should fill out the rules here with at least those for which GHC has primitives:

"realToFrac/Int->Double" realToFrac = int2Double :: Int -> Double
"realToFrac/Int->Float"  realToFrac = int2Float  :: Int -> Float

to the realToFrac and fromIntegral rules in GHC.Float

Change History (5)

comment:1 Changed 9 years ago by simonpj

difficulty: Unknown

Thanks Don. Would you care to offer a patch? (Don't forget to include comments that explain how big the performance improvement is; I find that giving a little program in that comment (as you do above) is a great way to capture the idea.)

I gather that when you say " least those for which GHC has primitives" you mean that there are some important ones missing. If so, propose away.


comment:2 Changed 9 years ago by dons

Resolution: fixed
Status: newclosed

I've pushed a patch adding the rules for Int->Double and Int->Float.


comment:3 Changed 9 years ago by simonpj

Thanks! I've found that comments in source files are more often read than those in patch messages, so I've transferred some of your comments into the source file itself.


comment:4 Changed 8 years ago by simonmar

Architecture: UnknownUnknown/Multiple

comment:5 Changed 8 years ago by simonmar

Operating System: UnknownUnknown/Multiple
Note: See TracTickets for help on using tickets.