Ticket #3586: faster-newArray-for-STU.dpatch

File faster-newArray-for-STU.dpatch, 7.1 KB (added by int-e, 4 years ago)

proposed fix. note that there are two patches in the bundle.

Line 
1Wed Oct 14 19:52:09 CEST 2009  Bertram Felgenhauer <int-e@gmx.de>
2  * Fix newArray performance (#3586)
3  newArray wasn't getting inlined, and thus not specialized for STUArray types.
4
5Wed Oct 14 20:01:24 CEST 2009  Bertram Felgenhauer <int-e@gmx.de>
6  * use forM_ rather than sequence_ (related to #3586)
7  It turns out that forM_ [0 .. n - 1] f  produces faster code than
8  sequence_ [f i | i <- [0 .. n - 1]].
9
10
11New patches:
12
13[Fix newArray performance (#3586)
14Bertram Felgenhauer <int-e@gmx.de>**20091014175209
15 Ignore-this: 335a897b5de209bdcd2932931eefd7cb
16 newArray wasn't getting inlined, and thus not specialized for STUArray types.
17] {
18hunk ./Data/Array/Base.hs 963
19        -- The INLINE is crucial, because until we know at least which monad   
20        -- we are in, the code below allocates like crazy.  So inline it,
21        -- in the hope that the context will know the monad.
22-    newArray (l,u) initialValue = do
23-        let n = safeRangeSize (l,u)
24-        marr <- unsafeNewArray_ (l,u)
25-        sequence_ [unsafeWrite marr i initialValue | i <- [0 .. n - 1]]
26-        return marr
27+    newArray = newArrayImpl
28 
29     {-# INLINE unsafeNewArray_ #-}
30     unsafeNewArray_ (l,u) = newArray (l,u) arrEleBottom
31hunk ./Data/Array/Base.hs 986
32     -- default initialisation with undefined values if we *do* know the
33     -- initial value and it is constant for all elements.
34 
35+{-# INLINE newArrayImpl #-}
36+newArrayImpl (l,u) initialValue = do
37+        let n = safeRangeSize (l,u)
38+        marr <- unsafeNewArray_ (l,u)
39+        sequence_ [unsafeWrite marr i initialValue | i <- [0 .. n - 1]]
40+        return marr
41+
42 instance MArray IOArray e IO where
43 #if defined(__HUGS__)
44     getBounds   = return . boundsIOArray
45}
46[use forM_ rather than sequence_ (related to #3586)
47Bertram Felgenhauer <int-e@gmx.de>**20091014180124
48 Ignore-this: 21e270df88eb12abb3cd856fa0126a1
49 It turns out that forM_ [0 .. n - 1] f  produces faster code than
50 sequence_ [f i | i <- [0 .. n - 1]].
51] {
52hunk ./Data/Array/Base.hs 30
53 
54 import Control.Monad.ST.Lazy ( strictToLazyST )
55 import qualified Control.Monad.ST.Lazy as Lazy (ST)
56+import Control.Monad ( forM_ )
57 import Data.Ix ( Ix, range, index, rangeSize )
58 import Foreign.C.Types
59 import Foreign.StablePtr
60hunk ./Data/Array/Base.hs 115
61 unsafeReplaceST :: (IArray a e, Ix i) => a i e -> [(Int, e)] -> ST s (STArray s i e)
62 unsafeReplaceST arr ies = do
63     marr <- thaw arr
64-    sequence_ [unsafeWrite marr i e | (i, e) <- ies]
65+    forM_ ies $ \ (i, e) -> unsafeWrite marr i e
66     return marr
67 
68 {-# INLINE unsafeAccumST #-}
69hunk ./Data/Array/Base.hs 122
70 unsafeAccumST :: (IArray a e, Ix i) => (e -> e' -> e) -> a i e -> [(Int, e')] -> ST s (STArray s i e)
71 unsafeAccumST f arr ies = do
72     marr <- thaw arr
73-    sequence_ [do
74+    forM_ ies $ \ (i, new) -> do
75         old <- unsafeRead marr i
76         unsafeWrite marr i (f old new)
77hunk ./Data/Array/Base.hs 125
78-        | (i, new) <- ies]
79     return marr
80 
81 {-# INLINE unsafeAccumArrayST #-}
82hunk ./Data/Array/Base.hs 131
83 unsafeAccumArrayST :: Ix i => (e -> e' -> e) -> e -> (i,i) -> [(Int, e')] -> ST s (STArray s i e)
84 unsafeAccumArrayST f e (l,u) ies = do
85     marr <- newArray (l,u) e
86-    sequence_ [do
87+    forM_ ies $ \ (i, new) -> do
88         old <- unsafeRead marr i
89         unsafeWrite marr i (f old new)
90hunk ./Data/Array/Base.hs 134
91-        | (i, new) <- ies]
92     return marr
93 
94 
95hunk ./Data/Array/Base.hs 443
96                   => (i,i) -> [(Int, e)] -> e -> ST s (UArray i e)
97 unsafeArrayUArray (l,u) ies default_elem = do
98     marr <- newArray (l,u) default_elem
99-    sequence_ [unsafeWrite marr i e | (i, e) <- ies]
100+    forM_ ies $ \ (i, e) -> unsafeWrite marr i e
101     unsafeFreezeSTUArray marr
102 
103 {-# INLINE unsafeFreezeSTUArray #-}
104hunk ./Data/Array/Base.hs 463
105                     => UArray i e -> [(Int, e)] -> ST s (UArray i e)
106 unsafeReplaceUArray arr ies = do
107     marr <- thawSTUArray arr
108-    sequence_ [unsafeWrite marr i e | (i, e) <- ies]
109+    forM_ ies $ \ (i, e) -> unsafeWrite marr i e
110     unsafeFreezeSTUArray marr
111 
112 {-# INLINE unsafeAccumUArray #-}
113hunk ./Data/Array/Base.hs 471
114                   => (e -> e' -> e) -> UArray i e -> [(Int, e')] -> ST s (UArray i e)
115 unsafeAccumUArray f arr ies = do
116     marr <- thawSTUArray arr
117-    sequence_ [do
118+    forM_ ies $ \ (i, new) -> do
119         old <- unsafeRead marr i
120         unsafeWrite marr i (f old new)
121hunk ./Data/Array/Base.hs 474
122-        | (i, new) <- ies]
123     unsafeFreezeSTUArray marr
124 
125 {-# INLINE unsafeAccumArrayUArray #-}
126hunk ./Data/Array/Base.hs 481
127                        => (e -> e' -> e) -> e -> (i,i) -> [(Int, e')] -> ST s (UArray i e)
128 unsafeAccumArrayUArray f initialValue (l,u) ies = do
129     marr <- newArray (l,u) initialValue
130-    sequence_ [do
131+    forM_ ies $ \ (i, new) -> do
132         old <- unsafeRead marr i
133         unsafeWrite marr i (f old new)
134hunk ./Data/Array/Base.hs 484
135-        | (i, new) <- ies]
136     unsafeFreezeSTUArray marr
137 
138 {-# INLINE eqUArray #-}
139hunk ./Data/Array/Base.hs 987
140 newArrayImpl (l,u) initialValue = do
141         let n = safeRangeSize (l,u)
142         marr <- unsafeNewArray_ (l,u)
143-        sequence_ [unsafeWrite marr i initialValue | i <- [0 .. n - 1]]
144+        forM_ [0 .. n - 1] $ \ i -> unsafeWrite marr i initialValue
145         return marr
146 
147 instance MArray IOArray e IO where
148hunk ./Data/Array/Base.hs 1061
149   (l,u) <- getBounds marr
150   n <- getNumElements marr
151   marr' <- newArray_ (l,u)
152-  sequence_ [do
153+  forM_ [0 .. n - 1] $ \ i -> do
154         e <- unsafeRead marr i
155         unsafeWrite marr' i (f e)
156hunk ./Data/Array/Base.hs 1064
157-        | i <- [0 .. n - 1]]
158   return marr'
159 
160 {-# INLINE mapIndices #-}
161hunk ./Data/Array/Base.hs 1073
162 mapIndices (l',u') f marr = do
163     marr' <- newArray_ (l',u')
164     n' <- getNumElements marr'
165-    sequence_ [do
166+    forM_ (range (l',u')) $ \ i' -> do
167         e <- readArray marr (f i')
168         unsafeWrite marr' (safeIndex (l',u') n' i') e
169hunk ./Data/Array/Base.hs 1076
170-        | i' <- range (l',u')]
171     return marr'
172 
173 -----------------------------------------------------------------------------
174hunk ./Data/Array/Base.hs 1778
175   (l,u) -> do
176     marr <- newArray_ (l,u)
177     let n = safeRangeSize (l,u)
178-    sequence_ [ unsafeWrite marr i (unsafeAt arr i)
179-              | i <- [0 .. n - 1]]
180+    forM_ [0 .. n - 1] $ \ i -> unsafeWrite marr i (unsafeAt arr i)
181     return marr
182 
183 thawSTUArray :: Ix i => UArray i e -> ST s (STUArray s i e)
184}
185
186Context:
187
188[TAG GHC 6.10.4 release
189Ian Lynagh <igloo@earth.li>**20090719123606]
190[TAG GHC 6.10.2 release
191Ian Lynagh <igloo@earth.li>**20090401221746]
192[TAG array 0.2.0.0
193Ian Lynagh <igloo@earth.li>**20081212141719]
194[TAG GHC 6.10.1 release
195Ian Lynagh <igloo@earth.li>**20081107191823]
196[Point the reader of the Data.Array docs in the direction of GHC.Arr
197Ian Lynagh <igloo@earth.li>**20081013172536]
198[remove unnecessary Data.Generics.* imports
199'Jose Pedro Magalhaes <jpm@cs.uu.nl>'**20081002082411]
200[Bump version number to 0.2.0.0
201Ian Lynagh <igloo@earth.li>**20080920155739]
202[TAG 6.10 branch has been forked
203Ian Lynagh <igloo@earth.li>**20080919123437]
204[TAG GHC 6.10 fork
205Ian Lynagh <igloo@earth.li>**20080919004905]
206Patch bundle hash:
207cc749a0dd6e36bb871a6957a4a7b79ab58a994a7