summaryrefslogtreecommitdiff
path: root/Git
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2017-01-31 18:40:42 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2017-01-31 19:06:22 -0400
commit7fd21be7f967bdc21530b730f595379b23fe1174 (patch)
treed2af9101541d8166b2035271967bb3ac01751e36 /Git
parent164466c987a7607a5f598b36e5b3111a68bd101f (diff)
Some optimisations to string splitting code.
Turns out that Data.List.Utils.split is slow and makes a lot of allocations. Here's a much simpler single character splitter that behaves the same (even in wacky corner cases) while running in half the time and 75% the allocations. As well as being an optimisation, this helps move toward eliminating use of missingh. (Data.List.Split.splitOn is nearly as slow as Data.List.Utils.split and allocates even more.) I have not benchmarked the effect on git-annex, but would not be surprised to see some parsing of eg, large streams from git commands run twice as fast, and possibly in less memory. This commit was sponsored by Boyd Stephen Smith Jr. on Patreon.
Diffstat (limited to 'Git')
-rw-r--r--Git/Command.hs8
-rw-r--r--Git/Config.hs2
-rw-r--r--Git/Construct.hs4
-rw-r--r--Git/Ref.hs2
4 files changed, 8 insertions, 8 deletions
diff --git a/Git/Command.hs b/Git/Command.hs
index adea7622e..f40dfabcd 100644
--- a/Git/Command.hs
+++ b/Git/Command.hs
@@ -91,16 +91,16 @@ pipeWrite params repo = withHandle StdinHandle createProcessSuccess $
pipeNullSplit :: [CommandParam] -> Repo -> IO ([String], IO Bool)
pipeNullSplit params repo = do
(s, cleanup) <- pipeReadLazy params repo
- return (filter (not . null) $ split sep s, cleanup)
+ return (filter (not . null) $ splitc sep s, cleanup)
where
- sep = "\0"
+ sep = '\0'
pipeNullSplitStrict :: [CommandParam] -> Repo -> IO [String]
pipeNullSplitStrict params repo = do
s <- pipeReadStrict params repo
- return $ filter (not . null) $ split sep s
+ return $ filter (not . null) $ splitc sep s
where
- sep = "\0"
+ sep = '\0'
pipeNullSplitZombie :: [CommandParam] -> Repo -> IO [String]
pipeNullSplitZombie params repo = leaveZombie <$> pipeNullSplit params repo
diff --git a/Git/Config.hs b/Git/Config.hs
index 65bd9b7ba..9b4c342a4 100644
--- a/Git/Config.hs
+++ b/Git/Config.hs
@@ -132,7 +132,7 @@ parse s
-- --list output will have an = in the first line
| all ('=' `elem`) (take 1 ls) = sep '=' ls
-- --null --list output separates keys from values with newlines
- | otherwise = sep '\n' $ split "\0" s
+ | otherwise = sep '\n' $ splitc '\0' s
where
ls = lines s
sep c = M.fromListWith (++) . map (\(k,v) -> (k, [v])) .
diff --git a/Git/Construct.hs b/Git/Construct.hs
index 765562212..489927880 100644
--- a/Git/Construct.hs
+++ b/Git/Construct.hs
@@ -26,7 +26,7 @@ module Git.Construct (
#ifndef mingw32_HOST_OS
import System.Posix.User
#endif
-import qualified Data.Map as M hiding (map, split)
+import qualified Data.Map as M
import Network.URI
import Common
@@ -143,7 +143,7 @@ remoteNamedFromKey :: String -> IO Repo -> IO Repo
remoteNamedFromKey k = remoteNamed basename
where
basename = intercalate "." $
- reverse $ drop 1 $ reverse $ drop 1 $ split "." k
+ reverse $ drop 1 $ reverse $ drop 1 $ splitc '.' k
{- Constructs a new Repo for one of a Repo's remotes using a given
- location (ie, an url). -}
diff --git a/Git/Ref.hs b/Git/Ref.hs
index 5b3b85324..2d8013738 100644
--- a/Git/Ref.hs
+++ b/Git/Ref.hs
@@ -144,6 +144,6 @@ legal allowonelevel s = all (== False) illegal
ends v = v `isSuffixOf` s
begins v = v `isPrefixOf` s
- pathbits = split "/" s
+ pathbits = splitc '/' s
illegalchars = " ~^:?*[\\" ++ controlchars
controlchars = chr 0o177 : [chr 0 .. chr (0o40-1)]