Hm, it seems then that another correct solution would be to {-# INLINE #-}
cFloatConv - it would get transformed to realToFrac everywhere, and GHC
would specialize it.

I'm now trying to check this, but somehow my ghc-pkg broke and I'm now
going to spend the next eternity recompiling gtk2hs from scratch with
enabled split-objs and enabled library-profiling, if you know what I mean...

I'll report back when I get any results.

On Wed, Nov 2, 2011 at 4:00 PM, <wagne...@seas.upenn.edu> wrote:

> If the problem really is that cFloatConv is using the generic
> fromRational . toRational implementation, then the correct solution is
> to simply _not define cFloatConv_ and use realToFrac everywhere. GHC
> already has tons of specialization rules for realToFrac. However,
> rewrite rules (which are what is generated by a specialization) are
> only syntactic. This, combined with the NOINLINE pragma you have on
> cFloatConv, means that they are never allowed to fire.
>
> ~d
>
> Quoting Eugene Kirpichov <ekirpic...@gmail.com>:
>
> > Sorry for re-sending, my previous attempt got ignored by gtk2hs-devel
> > mailing list as I wasn't subscribed. Now I am.
> >
> > On Wed, Nov 2, 2011 at 3:14 PM, Eugene Kirpichov <ekirpic...@gmail.com
> >wrote:
> >
> >> Yay!!!
> >>
> >> I made a small change in Types.chs and got my original
> cairo-binding-based
> >> program to be just as blazing fast. The only problem I have with this is
> >> that I used multiparameter type classes.
> >>
> >> Dear gtk2hs team! Is it possible to incorporate my changes? I'm pretty
> >> sure people will be happy by an order-of-magnitude speedup. Probably the
> >> stuff could be wrapped in #define's for those who aren't using GHC and
> >> can't use multiparameter type classes?
> >>
> >> I am pretty sure I could have done the same with rewrite rules, but I
> >> tried for a while and to no avail.
> >>
> >> FAILED SOLUTION: rewrite rules
> >> cFloatConv :: (RealFloat a, RealFloat b) => a -> b
> >> cFloatConv  = realToFrac
> >> {-# NOINLINE cFloatConv #-}
> >> {-# RULES "cFloatConv/float2Double" cFloatConv = float2Double #-}
> >> {-# RULES "cFloatConv/double2Float" cFloatConv = double2Float #-}
> >> {-# RULES "cFloatConv/self"         cFloatConv = id           #-}
> >>
> >> For some reason, the rules don't fire. Anyone got an idea why?
> >>
> >> SUCCEEDED SOLUTION: multiparameter type classes
> >>
> >> I rewrote cFloatConv like this:
> >>
> >> import GHC.Float
> >> class (RealFloat a, RealFloat b) => CFloatConv a b where
> >>   cFloatConv :: a -> b
> >>   cFloatConv = realToFrac
> >>
> >> instance CFloatConv Double Double where cFloatConv = id
> >> instance CFloatConv Double CDouble
> >> instance CFloatConv CDouble Double
> >> instance CFloatConv Float Float where cFloatConv = id
> >> instance CFloatConv Float Double where cFloatConv = float2Double
> >> instance CFloatConv Double Float where cFloatConv = double2Float
> >>
> >> and replaced a couple of constraints in functions below by usage of
> >> CFloatConv.
> >>
> >>
> >> On Wed, Nov 2, 2011 at 2:25 PM, Felipe Almeida Lessa <
> >> felipe.le...@gmail.com> wrote:
> >>
> >>> +gtk2hs-devel
> >>>
> >>> On Wed, Nov 2, 2011 at 8:15 AM, Eugene Kirpichov <ekirpic...@gmail.com
> >
> >>> wrote:
> >>> > Any idea how to debug why all the GMP calls?
> >>> > I'm looking at even the auto-generated source for cairo bindings,
> but I
> >>> > don't see anything at all that could lead to *thousands* of them.
> >>>
> >>> Found them.  Look at the Types module and you'll see
> >>>
> >>>  cFloatConv :: (RealFloat a, RealFloat b) => a -> b
> >>>  cFloatConv  = realToFrac
> >>>
> >>> This function (or its cousins peekFloatConv, withFloatConv...) are
> >>> used *everywhere*.
> >>>
> >>> Looking at this module with ghc-core we see that GHC compiled a
> >>> generic version of cFloatConv:
> >>>
> >>> Graphics.Rendering.Cairo.Types.$wcFloatConv
> >>>  :: forall a_a3TN b_a3TO.
> >>>     (RealFloat a_a3TN, RealFrac b_a3TO) =>
> >>>     a_a3TN -> b_a3TO
> >>> [GblId,
> >>>  Arity=3,
> >>>
> >>>  Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=3, Value=True,
> >>>         ConLike=True, Cheap=True, Expandable=True,
> >>>         Guidance=IF_ARGS [3 3 0] 12 0}]
> >>> Graphics.Rendering.Cairo.Types.$wcFloatConv =
> >>>  \ (@ a_a3TN)
> >>>    (@ b_a3TO)
> >>>    (w_s5zg :: RealFloat a_a3TN)
> >>>    (ww_s5zj :: RealFrac b_a3TO)
> >>>    (w1_s5zA :: a_a3TN) ->
> >>>    fromRational
> >>>      @ b_a3TO
> >>>      ($p2RealFrac @ b_a3TO ww_s5zj)
> >>>      (toRational
> >>>         @ a_a3TN
> >>>         ($p1RealFrac
> >>>            @ a_a3TN ($p1RealFloat @ a_a3TN w_s5zg))
> >>>         w1_s5zA)
> >>>
> >>> Note that this is basically cFloatConv = fromRational . toRational.
> >>>
> >>> *However*, GHC also compiled a Double -> Double specialization:
> >>>
> >>> Graphics.Rendering.Cairo.Types.cFloatConv1
> >>>  :: Double -> Double
> >>> [GblId,
> >>>  Arity=1,
> >>>
> >>>  Unf=Unf{Src=InlineStable, TopLvl=True, Arity=1, Value=True,
> >>>         ConLike=True, Cheap=True, Expandable=True,
> >>>         Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=False)
> >>>         Tmpl= \ (eta_B1 [Occ=Once!] :: Double) ->
> >>>                 case eta_B1 of _ { D# ww_a5v3 [Occ=Once] ->
> >>>                 case $w$ctoRational ww_a5v3
> >>>                 of _ { (# ww2_a5v8 [Occ=Once], ww3_a5v9 [Occ=Once] #)
> ->
> >>>                 $wfromRat ww2_a5v8 ww3_a5v9
> >>>                 }
> >>>                 }}]
> >>> Graphics.Rendering.Cairo.Types.cFloatConv1 =
> >>>  \ (eta_B1 :: Double) ->
> >>>    case eta_B1 of _ { D# ww_a5v3 ->
> >>>    case $w$ctoRational ww_a5v3
> >>>    of _ { (# ww2_a5v8, ww3_a5v9 #) ->
> >>>    $wfromRat ww2_a5v8 ww3_a5v9
> >>>    }
> >>>    }
> >>>
> >>> ...which is also equivalent to fromRational . toRational however with
> >>> the type class inlined!  Oh, god...
> >>>
> >>> Cheers,
> >>>
> >>> --
> >>> Felipe.
> >>>
> >>> _______________________________________________
> >>> Haskell-Cafe mailing list
> >>> haskell-c...@haskell.org
> >>> http://www.haskell.org/mailman/listinfo/haskell-cafe
> >>>
> >>
> >>
> >>
> >> --
> >> Eugene Kirpichov
> >> Principal Engineer, Mirantis Inc. http://www.mirantis.com/
> >> Editor, http://fprog.ru/
> >>
> >
> >
> >
> > --
> > Eugene Kirpichov
> > Principal Engineer, Mirantis Inc. http://www.mirantis.com/
> > Editor, http://fprog.ru/
> >
>
>
>
>
> ------------------------------------------------------------------------------
> RSA&#174; Conference 2012
> Save $700 by Nov 18
> Register now&#33;
> http://p.sf.net/sfu/rsa-sfdev2dev1
> _______________________________________________
> Gtk2hs-devel mailing list
> Gtk2hs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel
>



-- 
Eugene Kirpichov
Principal Engineer, Mirantis Inc. http://www.mirantis.com/
Editor, http://fprog.ru/
------------------------------------------------------------------------------
RSA&#174; Conference 2012
Save $700 by Nov 18
Register now&#33;
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
Gtk2hs-devel mailing list
Gtk2hs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel

Reply via email to