| 1 | Wed 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 | |
|---|
| 5 | Wed 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 | |
|---|
| 11 | New patches: |
|---|
| 12 | |
|---|
| 13 | [Fix newArray performance (#3586) |
|---|
| 14 | Bertram Felgenhauer <int-e@gmx.de>**20091014175209 |
|---|
| 15 | Ignore-this: 335a897b5de209bdcd2932931eefd7cb |
|---|
| 16 | newArray wasn't getting inlined, and thus not specialized for STUArray types. |
|---|
| 17 | ] { |
|---|
| 18 | hunk ./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 |
|---|
| 31 | hunk ./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) |
|---|
| 47 | Bertram 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 | ] { |
|---|
| 52 | hunk ./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 |
|---|
| 60 | hunk ./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 #-} |
|---|
| 69 | hunk ./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) |
|---|
| 77 | hunk ./Data/Array/Base.hs 125 |
|---|
| 78 | - | (i, new) <- ies] |
|---|
| 79 | return marr |
|---|
| 80 | |
|---|
| 81 | {-# INLINE unsafeAccumArrayST #-} |
|---|
| 82 | hunk ./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) |
|---|
| 90 | hunk ./Data/Array/Base.hs 134 |
|---|
| 91 | - | (i, new) <- ies] |
|---|
| 92 | return marr |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | hunk ./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 #-} |
|---|
| 104 | hunk ./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 #-} |
|---|
| 113 | hunk ./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) |
|---|
| 121 | hunk ./Data/Array/Base.hs 474 |
|---|
| 122 | - | (i, new) <- ies] |
|---|
| 123 | unsafeFreezeSTUArray marr |
|---|
| 124 | |
|---|
| 125 | {-# INLINE unsafeAccumArrayUArray #-} |
|---|
| 126 | hunk ./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) |
|---|
| 134 | hunk ./Data/Array/Base.hs 484 |
|---|
| 135 | - | (i, new) <- ies] |
|---|
| 136 | unsafeFreezeSTUArray marr |
|---|
| 137 | |
|---|
| 138 | {-# INLINE eqUArray #-} |
|---|
| 139 | hunk ./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 |
|---|
| 148 | hunk ./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) |
|---|
| 156 | hunk ./Data/Array/Base.hs 1064 |
|---|
| 157 | - | i <- [0 .. n - 1]] |
|---|
| 158 | return marr' |
|---|
| 159 | |
|---|
| 160 | {-# INLINE mapIndices #-} |
|---|
| 161 | hunk ./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 |
|---|
| 169 | hunk ./Data/Array/Base.hs 1076 |
|---|
| 170 | - | i' <- range (l',u')] |
|---|
| 171 | return marr' |
|---|
| 172 | |
|---|
| 173 | ----------------------------------------------------------------------------- |
|---|
| 174 | hunk ./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 | |
|---|
| 186 | Context: |
|---|
| 187 | |
|---|
| 188 | [TAG GHC 6.10.4 release |
|---|
| 189 | Ian Lynagh <igloo@earth.li>**20090719123606] |
|---|
| 190 | [TAG GHC 6.10.2 release |
|---|
| 191 | Ian Lynagh <igloo@earth.li>**20090401221746] |
|---|
| 192 | [TAG array 0.2.0.0 |
|---|
| 193 | Ian Lynagh <igloo@earth.li>**20081212141719] |
|---|
| 194 | [TAG GHC 6.10.1 release |
|---|
| 195 | Ian Lynagh <igloo@earth.li>**20081107191823] |
|---|
| 196 | [Point the reader of the Data.Array docs in the direction of GHC.Arr |
|---|
| 197 | Ian 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 |
|---|
| 201 | Ian Lynagh <igloo@earth.li>**20080920155739] |
|---|
| 202 | [TAG 6.10 branch has been forked |
|---|
| 203 | Ian Lynagh <igloo@earth.li>**20080919123437] |
|---|
| 204 | [TAG GHC 6.10 fork |
|---|
| 205 | Ian Lynagh <igloo@earth.li>**20080919004905] |
|---|
| 206 | Patch bundle hash: |
|---|
| 207 | cc749a0dd6e36bb871a6957a4a7b79ab58a994a7 |
|---|