[GHC] #876: Length is not a good consumer
GHC
cvs-ghc at haskell.org
Thu Feb 14 09:50:29 CET 2013
#876: Length is not a good consumer
--------------------------------------+-------------------------------------
Reporter: ariep@… | Owner:
Type: bug | Status: closed
Priority: lowest | Milestone: 7.6.2
Component: libraries/base | Version: 6.5
Resolution: fixed | Keywords: length
Os: Linux | Architecture: Unknown/Multiple
Failure: Runtime performance bug | Difficulty: Unknown
Testcase: perf/should_run/T876 | Blockedby:
Blocking: | Related:
--------------------------------------+-------------------------------------
Changes (by simonpj):
* status: new => closed
* testcase: list003 => perf/should_run/T876
* resolution: => fixed
Comment:
This patch to `GHC.List` makes `length` a good consumer, for what it's
worth. The nofib numbers didn't budge.
Simon
{{{
commit 82f56e5a331f9bbd5c8afda9e8d8ad71059e934b
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Thu Feb 14 08:22:08 2013 +0000
Make 'length' into a good consumer, fixing Trac #876
Trac #876 is the oldest ticket I have fixed in a long time.
I finally figured out how to make foldr behave in a non
space-leaky way for length.
Thanks to Andy for re-opening.
>---------------------------------------------------------------
GHC/List.lhs | 23 ++++++++++++++++++-----
1 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/GHC/List.lhs b/GHC/List.lhs index 02d6965..049aa2a 100644
--- a/GHC/List.lhs
+++ b/GHC/List.lhs
@@ -114,12 +114,25 @@ null (_:_) = False
-- | /O(n)/. 'length' returns the length of a finite list as an 'Int'.
-- It is an instance of the more general 'Data.List.genericLength',
-- the result type of which may be any kind of number.
+{-# NOINLINE [1] length #-}
length :: [a] -> Int
-length l = len l 0#
- where
- len :: [a] -> Int# -> Int
- len [] a# = I# a#
- len (_:xs) a# = len xs (a# +# 1#)
+length l = lenAcc l 0#
+
+lenAcc :: [a] -> Int# -> Int
+lenAcc [] a# = I# a#
+lenAcc (_:xs) a# = lenAcc xs (a# +# 1#)
+
+incLen :: a -> (Int# -> Int) -> Int# -> Int incLen _ g x = g (x +# 1#)
+
+-- These rules make length into a good consumer
+-- Note that we use a higher-order-style use of foldr, so that
+-- the accumulating parameter can be evaluated strictly
+-- See Trac #876 for what goes wrong otherwise {-# RULES
+"length" [~1] forall xs. length xs = foldr incLen I# xs 0#
+"lengthList" [1] foldr incLen I# = lenAcc #-}
-- | 'filter', applied to a predicate and a list, returns the list of
-- those elements that satisfy the predicate; i.e.,
}}}
--
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/876#comment:26>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list