lib: Consume list immediately in commodityStylesFromAmounts.
This reduced the maximum heap size per thread from ~850K to ~430K in a real-world register test.
This commit is contained in:
		
							parent
							
								
									150cf3f862
								
							
						
					
					
						commit
						a65ef7cd19
					
				| @ -92,6 +92,7 @@ module Hledger.Data.Journal ( | ||||
| ) | ||||
| where | ||||
| 
 | ||||
| import Control.Applicative ((<|>)) | ||||
| import Control.Monad.Except (ExceptT(..), runExceptT, throwError) | ||||
| import "extra" Control.Monad.Extra (whenM) | ||||
| import Control.Monad.Reader as R | ||||
| @ -102,9 +103,9 @@ import Data.Default (Default(..)) | ||||
| import Data.Function ((&)) | ||||
| import qualified Data.HashTable.Class as H (toList) | ||||
| import qualified Data.HashTable.ST.Cuckoo as H | ||||
| import Data.List (find, sortOn) | ||||
| import Data.List.Extra (groupSort, nubSort) | ||||
| import qualified Data.Map as M | ||||
| import Data.List (find, foldl', sortOn) | ||||
| import Data.List.Extra (nubSort) | ||||
| import qualified Data.Map.Strict as M | ||||
| import Data.Maybe (catMaybes, fromJust, fromMaybe, isJust, mapMaybe) | ||||
| #if !(MIN_VERSION_base(4,11,0)) | ||||
| import Data.Semigroup (Semigroup(..)) | ||||
| @ -1109,42 +1110,40 @@ journalInferCommodityStyles j = | ||||
| -- and this function never reports an error. | ||||
| -- | ||||
| commodityStylesFromAmounts :: [Amount] -> Either String (M.Map CommoditySymbol AmountStyle) | ||||
| commodityStylesFromAmounts amts = | ||||
|   Right $ M.fromList commstyles | ||||
|   where | ||||
|     commamts = groupSort [(acommodity as, as) | as <- amts] | ||||
|     commstyles = [(c, canonicalStyleFrom $ map astyle as) | (c,as) <- commamts] | ||||
| commodityStylesFromAmounts = | ||||
|     Right . foldr (\a -> M.insertWith canonicalStyle (acommodity a) (astyle a)) mempty | ||||
| 
 | ||||
| -- | Given a list of amount styles (assumed to be from parsed amounts | ||||
| -- in a single commodity), in parse order, choose a canonical style. | ||||
| canonicalStyleFrom :: [AmountStyle] -> AmountStyle | ||||
| -- canonicalStyleFrom [] = amountstyle | ||||
| canonicalStyleFrom ss = foldl' canonicalStyle amountstyle ss | ||||
| 
 | ||||
| -- TODO: should probably detect and report inconsistencies here. | ||||
| -- Though, we don't have the info for a good error message, so maybe elsewhere. | ||||
| -- | Given a list of amount styles (assumed to be from parsed amounts | ||||
| -- in a single commodity), in parse order, choose a canonical style. | ||||
| -- | Given a pair of AmountStyles, choose a canonical style. | ||||
| -- This is: | ||||
| -- the general style of the first amount, | ||||
| -- with the first digit group style seen, | ||||
| -- with the maximum precision of all. | ||||
| -- | ||||
| canonicalStyleFrom :: [AmountStyle] -> AmountStyle | ||||
| canonicalStyleFrom [] = amountstyle | ||||
| canonicalStyleFrom ss@(s:_) = | ||||
|   s{asprecision=prec, asdecimalpoint=Just decmark, asdigitgroups=mgrps} | ||||
| canonicalStyle :: AmountStyle -> AmountStyle -> AmountStyle | ||||
| canonicalStyle a b = a{asprecision=prec, asdecimalpoint=decmark, asdigitgroups=mgrps} | ||||
|   where | ||||
|     -- precision is maximum of all precisions | ||||
|     prec = maximumStrict $ map asprecision ss | ||||
|     prec = max (asprecision a) (asprecision b) | ||||
|     -- identify the digit group mark (& group sizes) | ||||
|     mgrps = headMay $ mapMaybe asdigitgroups ss | ||||
|     mgrps = asdigitgroups a <|> asdigitgroups b | ||||
|     -- if a digit group mark was identified above, we can rely on that; | ||||
|     -- make sure the decimal mark is different. If not, default to period. | ||||
|     defdecmark = | ||||
|       case mgrps of | ||||
|     defdecmark = case mgrps of | ||||
|         Just (DigitGroups '.' _) -> ',' | ||||
|         _                        -> '.' | ||||
|     -- identify the decimal mark: the first one used, or the above default, | ||||
|     -- but never the same character as the digit group mark. | ||||
|     -- urgh.. refactor.. | ||||
|     decmark = case mgrps of | ||||
|                 Just _ -> defdecmark | ||||
|                 _      -> headDef defdecmark $ mapMaybe asdecimalpoint ss | ||||
|         Just _  -> Just defdecmark | ||||
|         Nothing -> asdecimalpoint a <|> asdecimalpoint b <|> Just defdecmark | ||||
| 
 | ||||
| -- -- | Apply this journal's historical price records to unpriced amounts where possible. | ||||
| -- journalApplyPriceDirectives :: Journal -> Journal | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user