git.iko.soy/typeable/pandoc
on master help sign in
Optimized oneOfStringsCI.

The call to toLower in ciMatch was very expensive (and very often used), because toLower from Data.Char calls a fully unicode aware function. This optimization avoids the call to toLower for the most common, ASCII cases. This dramatically reduces the speed penalty that comes from enabling the `autolink_bare_uris` extension. The penalty is still substantial (in one test, from 0.33s to 0.44s), but nowhere near what it used to be.

commita6c167125fb423b365940401b45e5a95791b2fcf authorJohn MacFarlane <fiddlosopher@gmail.com> dateSat 2 Feb 2013, 18:46 (14 years ago) parent92acb24
1 file changed+9−3
src/Text/Pandoc/Parsing.hs+9−3
src/Text/Pandoc/Parsing.hs+9−3
@@ -152,8 +152,8 @@ import Text.Pandoc.Builder (Blocks, Inlines, rawBlock)
152152import qualified Text.Pandoc.UTF8 as UTF8 (putStrLn)
153153import Text.Parsec
154154import Text.Parsec.Pos (newPos)
155−import Data.Char ( toLower, toUpper, ord, isAscii, isAlphaNum, isDigit, isHexDigit,
156− isSpace )
155+import Data.Char ( toLower, toUpper, ord, chr, isAscii, isAlphaNum, isDigit,
156+ isHexDigit, isSpace )
157157import Data.List ( intercalate, transpose )
158158import Text.Pandoc.Shared
159159import qualified Data.Map as M
@@ -244,7 +244,13 @@ oneOfStrings = oneOfStrings' (==)
244244-- | Parses one of a list of strings (tried in order), case insensitive.
245245oneOfStringsCI :: [String] -> Parser [Char] st String
246246oneOfStringsCI = oneOfStrings' ciMatch
247− where ciMatch x y = toLower x == toLower y
247+ where ciMatch x y = toLower' x == toLower' y
248+ -- this optimizes toLower by checking common ASCII case
249+ -- first, before calling the expensive unicode-aware
250+ -- function:
251+ toLower' c | c >= 'A' && c <= 'Z' = chr (ord c + 32)
252+ | isAscii c = c
253+ | otherwise = toLower c
248254
249255-- | Parses a space or tab.
250256spaceChar :: Parser [Char] st Char