#2289: Needless reboxing of values when returning from a tight loop
-------------------------------------------+--------------------------------
    Reporter:  dons                        |        Owner:                  
        Type:  run-time performance bug    |       Status:  new             
    Priority:  normal                      |    Milestone:  6.12 branch     
   Component:  Compiler                    |      Version:  6.8.2           
    Severity:  normal                      |   Resolution:                  
    Keywords:  boxing, loops, performance  |   Difficulty:  Unknown         
    Testcase:                              |           Os:  Unknown/Multiple
Architecture:  Unknown/Multiple            |  
-------------------------------------------+--------------------------------
Comment (by simonmar):

 I believe this example fits into the same category.  We have a recursive
 tree traversal in the `ST` monad that returns an `Int`, and we want the
 `Int` unboxed.  Here's the complete code, both the version that doesn't
 optimise as well as we'd like, and the hand-optimised version:

 {{{
 {-# LANGUAGE BangPatterns, UnboxedTuples, MagicHash #-}
 module Test where

 import Data.Array.ST
 import Control.Monad.ST
 import Data.Array.Base
 import GHC.ST
 import GHC.Exts

 data Tree
       = Nil
       | Node {-#UNPACK#-} !Int
                           !Tree
                           !Tree
              {-#UNPACK#-} !Int

 #if 0
 -- The code we want to write
 traverse :: Tree -> STUArray s Int Int -> ST s Int
 traverse Nil                     !arr = return 0
 traverse (Node item child alt w) !arr = do
   childw <- traverse child arr
   altw   <- traverse alt arr
   itemw <- unsafeRead arr item
   unsafeWrite arr item (itemw + childw + w)
   return $! childw + w + altw
 #else
 -- The code we have to write
 traverse :: Tree -> STUArray s Int Int -> ST s Int
 traverse tree arr = ST $ \s ->
   case traverse' tree arr s of { (# s', i #) -> (# s', I# i #) }
   where
   traverse' Nil                             !arr s  = (# s, 0# #)
   traverse' (Node item child alt w@(I# w#)) !arr s0 =
      case traverse' child arr s0 of { (# s1, childw #) ->
      case traverse' alt arr   s1 of { (# s2, altw   #) ->
      case unsafeRead arr item of { ST f -> case f s2 of { (# s3, I# itemw
 #) ->
      case unsafeWrite arr item (I# itemw + I# childw + w) of { ST f ->
 case f s2 of { (# s4, _ #) ->
      (# s4, childw +# w# +# altw #)
      }}}}}}
 #endif
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2289#comment:16>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to