tek / splain

better implicit errors for scala
MIT License
370 stars 29 forks source link

0.1.16 significantly slows down compilation #9

Closed danslapman closed 7 years ago

danslapman commented 7 years ago

After updating to 0.1.16 I experience a 4x compilation slowdown on my work project: clean compilation with 0.1.15 took 49 secods, now it takes 203 seconds (without any errors).

I use the following configuration:

  "-P:splain:implicits:false",
  "-P:splain:breakinfix:12",

Unfortunately, I cannot reproduce this issue with any of my open projects :(

tek commented 7 years ago

I thought I noticed a slowdown during testing…the formatting routines are a little more complex now, I guess that huge implicit resolutions are impacted by that. I've been meaning to look into a way to delay the formatting until an error has occurred, because as it is, it happens whenever scalac generates an implicit message, which is multiple times for each (successful) resolution. Could be difficult though.

Anyway, the same types are formatted repeatedly for each implicit for some reason, maybe solving that will bring things back to normal.

tek commented 7 years ago

alright, delaying the formatting was easier than anticipated. could you test whether this brings compilation speed back to normal and close the issue if it does?

danslapman commented 7 years ago

@tek for sure! In a few hours.

nightscape commented 7 years ago

I just tried 0.1.17 and I think the slow-down is still present...

danslapman commented 7 years ago

@tek 0.1.17 did not fix the situation, compilation time is equal to with 0.1.16

tek commented 7 years ago

I see…so the slowdown isn't noticable with any other cases? I'll look into it some more, but eventually, you're going to have to come up with a test case.

tek commented 7 years ago

just tried compiling a project of mine with heavy shapeless use, takes forever…maybe it's the same reason.

danslapman commented 7 years ago

@tek I just got a 20% speed degradation on a small test project, I can share it if You still need a test case

tek commented 7 years ago

yes, please

danslapman commented 7 years ago

Hope it will help https://github.com/danslapman/splain-test

tek commented 7 years ago

alright, the problem is, that foundReqMsg is called lots of times during inference, independent of whether it eventually succeeds. This method is the only possible way of overriding that message, as all callers are objects or nested classes, so injecting a check if an actual error will be printed would require to duplicate half of the compiler code. I guess this just isn't possible from within a plugin.

tek commented 7 years ago

Good news, everyone! I implemented simple caching and it brought compilation times back to normal dimensions in my test case. Please verify! Also, you can have some statistics about the caches displayed by exporting the env var SPLAIN_CACHE_STATS.

danslapman commented 7 years ago

Just tested 0.1.20, in my case it even slighly (about 7%) faster than 0.1.15 👍

tek commented 7 years ago

great! makes sense, the issue existed before, just wasn't that noticable until formatting became more complex.