From e7c1e746187c2555a4fde6db0810b6441a804f87 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 8 Nov 2019 19:57:18 +0100 Subject: [PATCH 1/3] Fix #642 Bad performance/memory leak for long list literals A one-character fix that speeds up the formatting of long literals and drastically reduces memory usage. A very simple example is ```elm module Small exposing (x) x = [ 1, 2, 3 , 4] ``` But with a list literal of many thousands of elements. The newline forces all elements to get their own line. This is implemented as a fold, but in practice this would often perform ``` longList ++ shortList ``` By reversing the fold (from `foldl` to `foldr`) that turns into ``` shortList ++ longList ``` Which requires less traversals and memory. --- src/Box.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Box.hs b/src/Box.hs index 74bd45fd0..3f0645f66 100644 --- a/src/Box.hs +++ b/src/Box.hs @@ -119,7 +119,7 @@ stack1 children = [first] -> first boxes -> - foldl1 stack' boxes + foldr1 stack' boxes mapLines :: (Line -> Line) -> Box -> Box From fdc913c4fe3f55aacb6f9ad6ca0be33441e7cdb1 Mon Sep 17 00:00:00 2001 From: Aaron VonderHaar Date: Thu, 14 Nov 2019 20:59:38 -0800 Subject: [PATCH 2/3] Add scripts for profiling test files --- .gitignore | 1 + Shakefile.hs | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 72332601c..382837014 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /.shake/ /_build/ /generated/ +/_profile/ diff --git a/Shakefile.hs b/Shakefile.hs index 55a5c000e..cbc75bbe3 100644 --- a/Shakefile.hs +++ b/Shakefile.hs @@ -14,6 +14,8 @@ main = do } $ do StdoutTrim stackLocalInstallRoot <- liftIO $ cmd "stack path --local-install-root" StdoutTrim stackLocalBin <- liftIO $ cmd "stack path --local-bin" + StdoutTrim gitDescribe <- liftIO $ cmd "git" [ "describe", "--abbrev=8", "--always" ] + StdoutTrim gitSha <- liftIO $ cmd "git" [ "describe", "--always", "--match", "NOT A TAG", "--dirty" ] let elmFormat = stackLocalInstallRoot "bin/elm-format" <.> exe let shellcheck = stackLocalBin "shellcheck" <.> exe @@ -29,6 +31,7 @@ main = do phony "build" $ need [ elmFormat ] phony "stack-test" $ need [ "_build/stack-test.ok" ] + phony "profile" $ need [ "_build/tests/test-files/prof.ok" ] phony "clean" $ do cmd_ "stack clean" @@ -56,7 +59,6 @@ main = do "generated/Build_elm_format.hs" %> \out -> do alwaysRerun - (StdoutTrim gitDescribe) <- cmd "git" [ "describe", "--abbrev=8", "--always" ] writeFileChanged out $ unlines [ "module Build_elm_format where" , "" @@ -70,6 +72,15 @@ main = do need generatedSourceFiles cmd_ "stack build --test --no-run-tests" + "_build/bin/elm-format-prof" %> \out -> do + StdoutTrim profileInstallRoot <- liftIO $ cmd "stack path --profile --local-install-root" + sourceFiles <- getDirectoryFiles "" sourceFilesPattern + need sourceFiles + need generatedSourceFiles + cmd_ "stack build --profile --executable-profiling --library-profiling" + copyFileChanged (profileInstallRoot "bin/elm-format" <.> exe) out + + -- -- Haskell tests -- @@ -124,6 +135,15 @@ main = do cmd_ ("bash" <.> exe) script elmFormat writeFile' out "" + "_build/tests/test-files/prof.ok" %> \out -> do + let oks = + [ "_build/tests/test-files/good/Elm-0.17/prof.ok" + , "_build/tests/test-files/good/Elm-0.18/prof.ok" + , "_build/tests/test-files/good/Elm-0.19/prof.ok" + ] + need oks + writeFile' out (unlines oks) + -- Elm files @@ -138,6 +158,20 @@ main = do need oks writeFile' out (unlines elmFiles) + ("_build/tests/test-files/good/Elm-" ++ elmVersion ++ "/prof.ok") %> \out -> do + alwaysRerun + elmFiles <- getDirectoryFiles "" + [ "tests/test-files/good/Elm-" ++ elmVersion ++ "//*.elm" + ] + let oks = ["_profile" f -<.> (gitSha ++ ".prof") | f <- elmFiles] + need oks + writeFile' out (unlines oks) + + ("_profile/tests/test-files/good/Elm-" ++ elmVersion ++ "//*." ++ gitSha ++ ".prof") %> \out -> do + let source = dropDirectory1 $ dropExtensions out <.> "elm" + need [ "_build/bin/elm-format-prof", source ] + cmd_ "_build/bin/elm-format-prof" source "--output" "/dev/null" ("--elm-version=" ++ elmVersion) "+RTS" "-p" ("-po" ++ (out -<.> "")) + ("_build/tests/test-files/*/Elm-" ++ elmVersion ++ "//*.elm_formatted") %> \out -> do let source = dropDirectory1 $ out -<.> "elm" need [ elmFormat, source ] From f79639262ed4e09e55a23a4a05daf2a7a0b02248 Mon Sep 17 00:00:00 2001 From: Aaron VonderHaar Date: Thu, 14 Nov 2019 21:30:53 -0800 Subject: [PATCH 3/3] Update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8afec05b..773c37569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## master + +Bug fixes: + - performance is improved, allowing excessively long lists to be formatted without crashing + + ## 0.8.2 New features: