From fef7b80d8e988f6ad8de720a9e3a1098bc5f8a3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Sun, 2 Oct 2022 21:49:56 +0200 Subject: [PATCH 1/2] Use a Set in isInherited to speed up long extend lists Now the time is O(log(n)*m) instead of O(n*m) where n is the number of items in the extend list e.g. abstract FromWordNet = WordNet [ a_couple_Card, a_la_carte_Adv, a_la_mode_Adv, a_little_Card, ... ]; --- src/compiler/GF/Grammar/Grammar.hs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/compiler/GF/Grammar/Grammar.hs b/src/compiler/GF/Grammar/Grammar.hs index 587b09a9f..8b88561d2 100644 --- a/src/compiler/GF/Grammar/Grammar.hs +++ b/src/compiler/GF/Grammar/Grammar.hs @@ -78,6 +78,7 @@ import PGF.Internal (FId, FunId, SeqId, LIndex, Sequence, BindType(..)) import Data.Array.IArray(Array) import Data.Array.Unboxed(UArray) import qualified Data.Map as Map +import qualified Data.Set as Set import GF.Text.Pretty @@ -125,10 +126,12 @@ extends :: ModuleInfo -> [ModuleName] extends = map fst . mextend isInherited :: MInclude -> Ident -> Bool -isInherited c i = case c of - MIAll -> True - MIOnly is -> elem i is - MIExcept is -> notElem i is +isInherited c = + case c of + MIAll -> const True + MIOnly is -> let is' = Set.fromList is in (`Set.member` is') + MIExcept is -> let is' = Set.fromList is in (`Set.notMember` is') + inheritAll :: ModuleName -> (ModuleName,MInclude) inheritAll i = (i,MIAll) From a58c6d49d4b5d5cf750c36c9071279fccd9c468f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20K=C3=A4llberg?= Date: Sun, 2 Oct 2022 21:57:11 +0200 Subject: [PATCH 2/2] Extract the previous optimization to its own function --- src/compiler/GF/Grammar/Grammar.hs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/compiler/GF/Grammar/Grammar.hs b/src/compiler/GF/Grammar/Grammar.hs index 8b88561d2..448fa1657 100644 --- a/src/compiler/GF/Grammar/Grammar.hs +++ b/src/compiler/GF/Grammar/Grammar.hs @@ -129,9 +129,17 @@ isInherited :: MInclude -> Ident -> Bool isInherited c = case c of MIAll -> const True - MIOnly is -> let is' = Set.fromList is in (`Set.member` is') - MIExcept is -> let is' = Set.fromList is in (`Set.notMember` is') + MIOnly is -> elemOrd is + MIExcept is -> not . elemOrd is +-- | Faster version of `elem`, using a `Set`. +-- Make sure you give this the first argument _outside_ of the inner loop +-- +-- Example: +-- > myIntersection xs ys = filter (elemOrd xs) ys +elemOrd :: Ord a => [a] -> a -> Bool +elemOrd list = (`Set.member` set) + where set = Set.fromList list inheritAll :: ModuleName -> (ModuleName,MInclude) inheritAll i = (i,MIAll)