Hi there, GHC can often do a pretty good job at optimising generics. I wrote a paper that looks at that in detail:
José Pedro Magalhães. Optimisation of Generic Programs through Inlining. In 24th Symposium on Implementation and Application of Functional Languages (IFL'12), 2013. http://dreixel.net/research/pdf/ogpi.pdf Cheers, Pedro On Sat, Aug 22, 2015 at 11:26 PM, Ömer Sinan Ağacan <omeraga...@gmail.com> wrote: > Hi all, > > I'm very confused by an optimization GHC is doing. I have this code: > > > data Tree a = Leaf a | Branch (Tree a) (Tree a) > deriving (Generic, Show, NFData) > > data Tree1 a = Leaf1 a | Branch1 (Tree1 a) (Tree1 a) > deriving (Show) > > instance NFData a => NFData (Tree1 a) where > rnf (Leaf1 a) = rnf a > rnf (Branch1 t1 t2) = rnf t1 `seq` rnf t2 > > > When I benchmarked rnf calls I realized that they're too close, and I > looked at > simplifier outputs. I believe these are relevant parts: > > Rec { > Main.$fNFDataTree_$crnf [Occ=LoopBreaker] > :: forall a_ab5v. NFData a_ab5v => Tree a_ab5v -> () > Main.$fNFDataTree_$crnf = > \ (@ a17_ab5v) > ($dNFData_ab5w :: NFData a17_ab5v) > (eta_B1 :: Tree a17_ab5v) -> > case eta_B1 of _ [Occ=Dead] { > Leaf g1_aaHO -> > ($dNFData_ab5w > `cast` (Control.DeepSeq.NTCo:NFData[0] <a17_ab5v>_N > :: NFData a17_ab5v ~R# (a17_ab5v -> ()))) > g1_aaHO; > Branch g1_aaHP g2_aaHQ -> > case Main.$fNFDataTree_$crnf @ a17_ab5v $dNFData_ab5w g1_aaHP > of _ [Occ=Dead] { () -> > Main.$fNFDataTree_$crnf @ a17_ab5v $dNFData_ab5w g2_aaHQ > } > } > end Rec } > > Rec { > Main.$fNFDataTree1_$crnf [Occ=LoopBreaker] > :: forall a_abd4. NFData a_abd4 => Tree1 a_abd4 -> () > Main.$fNFDataTree1_$crnf = > \ (@ a17_abd4) > ($dNFData_abd5 :: NFData a17_abd4) > (eta_B1 :: Tree1 a17_abd4) -> > case eta_B1 of _ [Occ=Dead] { > Leaf1 a18_a4tg -> > ($dNFData_abd5 > `cast` (Control.DeepSeq.NTCo:NFData[0] <a17_abd4>_N > :: NFData a17_abd4 ~R# (a17_abd4 -> ()))) > a18_a4tg; > Branch1 t1_a4th t2_a4ti -> > case Main.$fNFDataTree1_$crnf @ a17_abd4 $dNFData_abd5 t1_a4th > of _ [Occ=Dead] { () -> > Main.$fNFDataTree1_$crnf @ a17_abd4 $dNFData_abd5 t2_a4ti > } > } > end Rec } > > First one is generated by GHC and second one is hand-written. If you > compare, > you'll see that they're identical. This looks like some serious magic, > because > first one is generated from a default method that uses Generic methods and > types. Does anyone know how is that possible? Which optimization passes are > involved in this? > > Thanks. > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs >
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs