summaryrefslogtreecommitdiff
path: root/testsuite/tests/perf/should_run/T3245.hs
diff options
context:
space:
mode:
Diffstat (limited to 'testsuite/tests/perf/should_run/T3245.hs')
-rw-r--r--testsuite/tests/perf/should_run/T3245.hs50
1 files changed, 50 insertions, 0 deletions
diff --git a/testsuite/tests/perf/should_run/T3245.hs b/testsuite/tests/perf/should_run/T3245.hs
new file mode 100644
index 0000000000..f52fc27303
--- /dev/null
+++ b/testsuite/tests/perf/should_run/T3245.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE ExistentialQuantification #-}
+
+-- The second version (count2) took ages with GHC 6.12
+-- because the typeOf function was not properly memoised
+
+import Data.Typeable
+import System.CPUTime
+
+size :: Int
+size = 40000 -- This was big enough to take 5 seconds in
+ -- the bad case on my machine.
+
+data Any = forall a. (Typeable a) => Any a
+
+int_type, int_list_type :: TypeRep
+int_type = typeOf (undefined :: Int)
+int_list_type = typeOf (undefined :: [Int])
+
+count1 :: [Any] -> Int
+count1 [] = 0
+count1 (Any x:xs) = count1 xs + (if typeOf x == int_type then 1 else 0)
+
+doTime x = do
+ start <- getCPUTime
+ putStr "Result: "
+ print x
+ stop <- getCPUTime
+ putStr "Time(sec): "
+ print (round $ fromIntegral (stop - start) / 1e12)
+ -- The 'round' rounds to an integral number of seconds
+ -- Should be zero if things are working right!
+
+main = do
+ let list = [MkT | i <- [1..size :: Int]]
+ putStrLn "count1"
+ let x = map Any list
+ doTime $ count1 x
+ doTime $ count1 x
+ doTime $ count1 x
+ putStrLn ""
+ putStrLn "count2"
+ let x = map (Any . (:[])) list
+ doTime $ count1 x
+ doTime $ count1 x
+ doTime $ count1 x
+
+data T = MkT
+tcname :: TyCon
+tcname = mkTyCon "T"
+instance Typeable T where { typeOf _ = mkTyConApp tcname [] }