-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Quadratic performance issues #32
Comments
Changing
This is with git bisect points at 6e01b2e and ghc/ghc@ac88f11. I tested the same change in GHC's copy of pretty (compiler/utils/Pretty), hoping it would make GHC massively faster! Unfortunately, it just had a negative effect on T3294:
|
Interesting. Well, the bug seems to hit only for certain kinds of nesting. But I have a few applications where I think it matters. And I have seen horrendous ghc and/or haddock runtimes for modules with hundreds of identifiers, e.g., in OpenGLRaw, and I have a hunch that this is related. You could try your patched ghc on these. I think 1second runtime for outputting 2k chars is still way high. For a similar test case with wl-pprint, it is more like 10 millisecs (but the combinators have different behaviour) |
I started debugging a stack overflow in Hoogle, see ndmitchell/hoogle#167, and it brought me to exactly this location. Specifically, given the operation:
This takes an unbounded amount of stack. If I replace:
Then it takes a constant amount of stack. It turns an O(n) memory algorithm into an O(1) algorithm, so seems like it should be considered a fix. @dterei, any thoughts? |
Sure. Do you mind submitting a PR with a test-case please? |
Sure. @thomie, I intend to remove that one bang, do you have any others I should include in the ticket? I found an even better test case, |
Fine by me. In case you know the answer, it would be great if you could add a comment or Note explaining why the other |
To be clear, I can demonstrate that one particular bang is harmful - I have no opinion on the others - but my guess is someone had bangs and thought they added performance so sprayed them with a machine gun. It's a standard Haskell optimisation without benchmarking trick 😞 |
I am glad that this issue is getting some attention. The worrisome thing is that my benchmark above is basically an iteration of a random (!) small context |
@jwaldmann - so I have one specific place which causes a more discrete regression (overly strict, different space complexity) - so is worth fixing independent of any performance measurements. Is it worth waiting for your benchmarks or shall I pull request it today? |
Don't wait for me. I made this for testing: https://github.com/jwaldmann/pretty-test |
Pull request for my piece as #35. |
For reference, here's the "winner" (most expensive context with depth 3 -- according to SmallCheck).
This is quite consistent for ghc-7.6.3, 7.8.4, 7.10.3, while ghc-8.0.1 is better by one second. |
What does the original prettyprint paper ( http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.8777 ) say about (asymptotic) performance? There are no exact claims or proofs, but end of Section 9 has "seems to grow slightly faster than linearly" and "far superior to O(n^2)". Really? Here is the runtimes for rendering iterations of context mentioned previously (x axis: iterations, y axis: time in seconds, average over 3 executions). (forgive the crude rendering) Looks accidentally quadratic ? I think that for a (pretty)printing library, anything more than linear is unacceptable , and as long as the behaviour is not fixed, "dangerous" combinators must be red-flagged in the API docs. What are these dangerous combinators? Everything that has an "either .. or" ? ( Detection of non-linearity in pretty's code would really make a nice test case for automated analysis of runtime complexity of programs. I can advertise this at http://cl-informatik.uibk.ac.at/users/tpowell/lca but don't expect immediate results ... Two technical points here: linear, quadratic, etc. - in what parameter exactly? Size of input? Size of output?
|
From what I've read of the code I would be shocked if it wasn't quadratic. It seems to regularly be traversing the entire tree to ensure global properties, whereas I would expect it to consider all Doc values in some normal form and then use smart constructors to guarantee that without traversing downwards. |
This is backport of [1] for GHC's copy of Pretty. See Note [Differences between libraries/pretty and compiler/utils/Pretty.hs]. [1] http://git.haskell.org/packages/pretty.git/commit/bbe9270c5f849a5bb74c9166a5f4202cfb0dba22 haskell/pretty#32 haskell/pretty#35 Reviewers: bgamari, austin Reviewed By: austin Differential Revision: https://phabricator.haskell.org/D2397 GHC Trac Issues: #12227
This is backport of [1] for GHC's copy of Pretty. See Note [Differences between libraries/pretty and compiler/utils/Pretty.hs]. [1] http://git.haskell.org/packages/pretty.git/commit/bbe9270c5f849a5bb74c9166a5f4202cfb0dba22 haskell/pretty#32 haskell/pretty#35 Reviewers: bgamari, austin Reviewed By: austin Differential Revision: https://phabricator.haskell.org/D2397 GHC Trac Issues: #12227 (cherry picked from commit 89a8be7)
This is backport of [1] for GHC's copy of Pretty. See Note [Differences between libraries/pretty and compiler/utils/Pretty.hs]. [1] http://git.haskell.org/packages/pretty.git/commit/bbe9270c5f849a5bb74c9166a5f4202cfb0dba22 haskell/pretty#32 haskell/pretty#35 Reviewers: bgamari, austin Reviewed By: austin Differential Revision: https://phabricator.haskell.org/D2397 GHC Trac Issues: #12227 (cherry picked from commit 89a8be7)
The pretty package had an issue here; luckily, prettyprinter does not. See haskell/pretty#32
Try this:
on my machine:
This testcase is simplified from https://ghc.haskell.org/trac/ghc/ticket/7666
I think this bug (gut feeling - some quadratic behaviour) has been sitting there for a long time.
I do think this is serious. I think it also hurts haddock.
pretty-1.1.3.2 for ghc-8.0.0.20160111 and pretty-1.1.2.0 for ghc-7.10.3
The text was updated successfully, but these errors were encountered: