7

I'm currently using Stack to build a project, which totals about 80 modules and 13,000 lines of code. Currently, compilation takes about 3 minutes for a minor change in my types files, which is unacceptable -- it prevents me from rapidly testing my code via stack ghci. It also significantly slows down a number of things: for instance, pair programming with peers or consulting with experts.

I would like to be able to figure out why compilation is taking so long, and what I can do to speed it up. Is there some way to profile compilation times?

Additionally, how can I tell whether it is stack or ghc that is slow?

I know about setting -O0, though this does not seem to help compilation times. I also know that TemplateHaskell and Typeclass Resolution can take a while -- is there any way I can get better resolution on how long these are taking?

Note: i have seen Speed up compilation in GHC, but that was from 2013, and hdevtools currently does not work on my setup.

Community
  • 1
  • 1
Timothy Chu
  • 153
  • 1
  • 9
  • You mention "compilation" several times but you also say you are using ghci. Are you compiling or interpreting? It makes a big difference. Compiling with `-O0` is not the same as interpreting, and if you are interpreting, then the `-O` switch does nothing anyways. What is your compilation time from scratch, i.e. how does it compare to the 3 minutes? If you make a change at the module at the top of the hierarchy, then it will recompile every single module - in general it couldn't tell whether it has to or not. – user2407038 Feb 13 '16 at 03:25
  • Also, TH does indeed cause massive slowdowns past a few hundred lines of generated code or so. There is no way around it, other than to improve the implementation of TH. You can sometimes speed up TH by reducing the number of splices (i.e. moving multiple splices into a single splice). If you are working on a module with a lot of TH, but not changing that TH code, consider moving the TH to a separate module. – user2407038 Feb 13 '16 at 03:28
  • well, I sometimes compile (stack install), sometimes I use stack ghci and its set up to autoload my entire project. They both take about the same time. My bad for conflating the two. – Timothy Chu Feb 13 '16 at 03:53
  • It's very surprising & unexpected that a compile and interpret take the same amount of time! I am not familiar with stack, so I don't know what commands it actually runs when you do `stack install` as compared to `stack ghci`. If you could discover this it may be helpful. Have you tried it just with `cabal` - i.e. `cabal build` vs. `cabal repl`? If these two differ significantly, then you know stack is doing something funnny. If they do not, then something weird is up with your proj (perhaps compile time is mainly dominated by TH or large type reductions? Can you give details of the proj?) – user2407038 Feb 13 '16 at 03:59
  • Stack is written in Haskell, you can profile it with RTS options like any other Haskell programs. – zakyggaps Feb 13 '16 at 07:53
  • @user2407038 : For some reason, stack ghci tells me it's compiling my project, instead of just interpreting it. So I suppose it is not interpreting that is taking a while, but that stack ghci is actually compiling my project (not sure why). Compile time is dominated by my Type files, some of which have a lot of TH and some of which don't. @ zakygapps. This sounds like an answer that's great for someone who's an expert at Stack, but as someone who without context about stack's internals it is not helpful. What concrete steps would I take in order to profile compilation time of my program? – Timothy Chu Feb 13 '16 at 19:19
  • @TimothyChu If stack is compiling your project, then launching GHCI with the compiled project in scope of the interpreter, then you aren't interpreting your project, you are compiling it. You will *never* have any compilation time reduction with this method. Profiling anything won't help here. Again, I don't know much about stack, but you must get it to launch the project itself in the interpreter. Or, `cabal repl` will probably work, if the GHC provided by stack is in the PATH (if not place it there temporarily or permanently). – user2407038 Feb 14 '16 at 03:27
  • Got it. I ended up solving this problem by using stack install --fast. Doesn't tell me why compilation times are long, but it does make my build times tolerable. Can you explain what you mean when you say 'launching GHCI with the compiled project in scope of the interpreter? – Timothy Chu Feb 15 '16 at 20:07
  • 1
    @TimothyChu if you found the solution to your question, you should post it as an answer so this question doesn't remain unanswered... – sclv Mar 04 '16 at 03:10
  • I have not! But thank you for the reminder. – Timothy Chu Jul 04 '16 at 04:27
  • 1
    Depending on the module graph of the package, I sometimes see handy speedups when I add `--ghc-options -j3` to `stack build`. – sjakobi Nov 23 '16 at 18:15

1 Answers1

2

In case this question is still relevant, you could try this:

stack ghci --fast --no-build --ghc-options="-fbyte-code"

IIRC using this got me the quickest results with stack ghci.

If this doesn't help enough, you could look in the direction of --ghc-options="-dshow-passes". I myself am also looking in this direction currently to try to speed up a build/ghci-reload.

Wizek
  • 4,854
  • 2
  • 25
  • 52