[commit: ghc] master: Pretty: improving the space/time performance of vcat, hsep, hcat (#10735) (f903949)

git at git.haskell.org git at git.haskell.org
Wed Aug 12 14:21:07 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/f903949beee3a4e0a925003b5553066c9f513c11/ghc

>---------------------------------------------------------------

commit f903949beee3a4e0a925003b5553066c9f513c11
Author: Thomas Miedema <thomasmiedema at gmail.com>
Date:   Wed Aug 5 10:31:46 2015 +0200

    Pretty: improving the space/time performance of vcat, hsep, hcat (#10735)
    
    After 5d57087e314bd484dbe14958f9b422be3ac6641a ("Pretty: fix a broken
    invariant"), T3294 showed 50% more max_bytes_used (#3294). After this
    commit, max_bytes_used is back to what it was before, and the test
    passes again.
    
    This is a backport of a bug fix by Benedikt Huber (#2393), from commit
    1e50748beaa4bd2281d323b18ea51c786bba04a1 in the pretty library.
    
    From https://mail.haskell.org/pipermail/libraries/2008-June/009991.html:
    
        vcat (hsep,cat) is implemented in an unneccessarily strict way.
        We only get some output after all of vcat's arguments are evaluated
        and checked against being Empty.
        This can be improved by only checking the right argument of foldr
        against being Empty, and
        then applying an Empty-filter on the resulting Doc. Space improvement
        is obvious.
        The microbenchmark (code.haskell.org/~bhuber/Text/PrettyPrint/
        HughesPJPerfCheck.hs) suggests that
        the improvements in time are remarkable too.


>---------------------------------------------------------------

f903949beee3a4e0a925003b5553066c9f513c11
 compiler/utils/Pretty.hs | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/compiler/utils/Pretty.hs b/compiler/utils/Pretty.hs
index 29a7b84..4aae2c8 100644
--- a/compiler/utils/Pretty.hs
+++ b/compiler/utils/Pretty.hs
@@ -529,15 +529,15 @@ reduceDoc p              = p
 
 -- | List version of '<>'.
 hcat :: [Doc] -> Doc
-hcat = foldr (<>)  empty
+hcat = reduceAB . foldr (beside_' False) empty
 
 -- | List version of '<+>'.
 hsep :: [Doc] -> Doc
-hsep = foldr (<+>) empty
+hsep = reduceAB . foldr (beside_' True)  empty
 
 -- | List version of '$$'.
 vcat :: [Doc] -> Doc
-vcat = foldr ($$)  empty
+vcat = reduceAB . foldr (above_' False) empty
 
 -- | Nest (or indent) a document by a given number of positions
 -- (which may also be negative).  'nest' satisfies the laws:
@@ -584,6 +584,19 @@ mkUnion :: Doc -> Doc -> Doc
 mkUnion Empty _ = Empty
 mkUnion p q     = p `union_` q
 
+beside_' :: Bool -> Doc -> Doc -> Doc
+beside_' _ p Empty = p
+beside_' g p q     = Beside p g q
+
+above_' :: Bool -> Doc -> Doc -> Doc
+above_' _ p Empty = p
+above_' g p q     = Above p g q
+
+reduceAB :: Doc -> Doc
+reduceAB (Above  Empty _ q) = q
+reduceAB (Beside Empty _ q) = q
+reduceAB doc                = doc
+
 nilAbove_ :: RDoc -> RDoc
 nilAbove_ = NilAbove
 



More information about the ghc-commits mailing list