On 2011-04-04 13:54 +0200, Bas van Dijk wrote:
> However, I noticed I had a lot of conversions from Vector Double to
> Vector CDouble and visa versa in my code:
> 
> import Data.Vector.Storable ( Vector )
> 
> mapRealToFrac ∷ (Storable α, Storable β, Real α, Fractional β)
>               ⇒ Vector α → Vector β
> mapRealToFrac = VS.map realToFrac
> 
> When I replace this with:
> 
> mapRealToFrac = unsafeCoerce
> 
> My application computes the same result but does it 28 times faster!

Note that even if Double and CDouble have identical representations,
unsafeCoerce does not perform the same conversion as realToFrac -- the
latter does conversion to/from Rational and thus munges all values not
representable therein.  This also happens to be why it is slooooooooow.
Some real examples, in GHCi:

  > realToFrac (0/0 :: Double) :: CDouble
  -Infinity
 
  > unsafeCoerce (0/0 :: Double) :: CDouble
  NaN
 
  > realToFrac (-0 :: Double) :: CDouble
  0.0
 
  > unsafeCoerce (-0 :: Double) :: CDouble
  -0.0

Using realToFrac to convert between different floating types is even
more fun:

  > realToFrac (1/0 :: Float) :: Double
  3.402823669209385e38

Nice!

> My question are:
> 
> 1) Is this always safe? In other words: are the runtime
> representations of Double and CDouble always equivalent or do they
> vary between platforms?

Probably not, but realToFrac isn't really "safe", either (as above).

> 2) Can the same improvement be accomplished using RULE pragma's?

No, because the two methods do not compute the same function.
However, there are (or were) broken RULE pragmas in GHC which
do this sort of transformation.  Such RULEs make realToFrac
really fun because your program's correctness will depend on
whether or not GHC decides to inline things.

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to