Don't add flag to conflict set when true and false introduce the same conflict.
A DependencyReason contains flags paired with values FlagTrue, FlagFalse, or FlagBoth, where FlagBoth means that the dependency was introduced by either value of the flag and was lifted out of a conditional. In the previous commit, when a dependency led to a conflict, all flags in the DependencyReason were added to the error message and conflict set. This commit avoids adding flags with value FlagBoth to the conflict set, because they can have a negative effect on goal order: After the solver encounters a conflict involving such a flag, it starts to prefer the flag when choosing goals, due to the solver's conflict counting feature. The solver shouldn't prefer the flag goal because it didn't actually need to choose the flag to see the dependency. Flags with value FlagBoth are still useful for error messages, though. I measured the performance of the last two commits by comparing commit fc3ef2a7 (master) with this commit. I did all testing with GHC 8.0.1 and 'index-state(hackage.haskell.org) = 2017-06-11T02:16:39Z'. I ran each version of cabal (cabal install --dry-run) on each package on Hackage and looked for packages with a difference in run time of at least 10%. Then I reran cabal on those packages to narrow down the list further (The results were noisy). Here are the average run times from five runs with the remaining packages: package master result master time (seconds) branch result branch time (seconds) speedup concraft backjump limit 5.67 backjump limit 4.89 1.16 forml backjump limit 10.26 backjump limit 8.85 1.16 hack-handler-simpleserver backjump limit 6.28 no solution 1.96 3.21 hack-middleware-clientsession backjump limit 17.86 no solution 1.95 9.14 haskore backjump limit 5.21 no solution 1.67 3.12 haskore-synthesizer no solution 23.14 no solution 2.21 10.49 language-gcl no solution 3.06 no solution 2.31 1.33 ms backjump limit 61.68 no solution 7.95 7.76 nerf solution 4.1 backjump limit 5.87 0.7 puzzle-draw solution 56.28 solution 5.31 10.6 react-haskell backjump limit 44.23 backjump limit 14.46 3.06 reflex-transformers no solution 2.18 no solution 1.9 1.15 shpider backjump limit 7.44 solution 1.88 3.95 thorn backjump limit 11.11 backjump limit 4.44 2.5 Both versions of cabal hit the backjump limit in four of the cases, so they don't really tell us which version performed better. All but one of the others are improvements. I looked at a few of the logs, and, as far as I can tell, most of the improvements are due to flags being used in conflict counting. This behavior is similar to #4147, which was reverted. The log for 'nerf', the one package that had worse performance, showed that the solver chose some flags earlier, but I didn't see any other reason for the slowdown. The solver found a solution when I used '--max-backjumps -1'. These differences in run time are caused by differences in goal order and/or backjumping, but I also wanted to compare performance when the solver went through similar steps on master and the branch. I found two commands that led to very similar -v3 output between the cabal versions. Presumably, package flags didn't cause many conflicts in these runs. cabal install --dry-run --max-backjumps -1 gi-glib happstack cabal install --dry-run yesod I took the average of three runs. There wasn't a big difference between master and the branch. packages result master time (seconds) branch time (seconds) master memory (MB) branch memory (MB) gi-glib, happstack no solution 30.02 30.70 245 245 yesod solution 3.53 3.55 239 239.3
Showing
- cabal-install/Distribution/Solver/Modular/Dependency.hs 14 additions, 12 deletionscabal-install/Distribution/Solver/Modular/Dependency.hs
- cabal-install/Distribution/Solver/Modular/Explore.hs 1 addition, 1 deletioncabal-install/Distribution/Solver/Modular/Explore.hs
- cabal-install/Distribution/Solver/Modular/Linking.hs 6 additions, 5 deletionscabal-install/Distribution/Solver/Modular/Linking.hs
Loading
Please register or sign in to comment