[Haskell-cafe] Fast conversion between Vector Double and Vector CDouble

Bas van Dijk v.dijk.bas at gmail.com
Mon Apr 4 15:41:22 CEST 2011


On 4 April 2011 14:41, Daniel Fischer <daniel.is.fischer at googlemail.com> wrote:
> On Monday 04 April 2011 13:54:39, Bas van Dijk wrote:
>> Hello,
>>
>> I just rewrote my levmar library[1] to use Vectors (from the vector
>> package[2]) instead of lists. I was expecting to see a significant
>> performance improvement. Unfortunately I only saw a 10% improvement.
>> 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!
>>
>> 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?
>
> It's not always safe, it seems to be different for NHC.
> In Foreign.C.Types, you find
>
> #ifndef __NHC__
> <snip> -- | These types are are represented as @newtype at s of
> <paraphrase> the corresponding Haskell types
> <snip>
> #else
> <snip>
> #endif
>
> for the integral and floating types.
> So for the time being, it's safe except possibly on NHC, as long as it is
> (and can be) only used to convert between the corresponding Haskell and C
> types
> (so
>
> #ifdef __NHC__
> mapRealToFrac = VS.map realToFrac
> #else
> mapRealToFrac = unsafeCoerce
> #endif
>
> would also cater for NHC).
>
>>
>> 2) Can the same improvement be accomplished using RULE pragma's?
>
> For GHC, probably, but rule-firings aren't always predictable.
> For example, it could be that the rule for realToFrac fires first.
>
>>
>> 3) Are there disadvantages of using CDouble instead of Double in the
>> levmar API?
>
> You'd have to write the conversion code every time you use it from Haskell,
> wouldn't you?
>
>> For some reason it feels wrong to use CDouble in the API
>> but I don't have a good argument against it yet.
>>
>> Thanks,
>>
>> Bas
>>
>> [1] http://hackage.haskell.org/package/levmar
>> [2] http://hackage.haskell.org/package/vector
>

Thanks for the clarification Daniel.

I just read[1] it's also possible to directly use Double and Float in
an FFI import declaration. I always assumed you could only use the C
types from Foreign.C.Types.
So I think I'm going to change bindings-levmar[2] to use Double and
Float instead of CDouble and CFloat. This way I don't even need to
map.

Bas

[1] http://www.haskell.org/onlinereport/haskell2010/haskellch8.html#x15-1560008.4.2
[2] http://hackage.haskell.org/package/bindings-levmar



More information about the Haskell-Cafe mailing list