Can I find out what kapt was actually doing? In my...
# announcements
p
Can I find out what kapt was actually doing? In my build scan I have 1:12 minutes of
kaptGenerateStubsDevKotlin
even though I only have
kapAndroidTest
,
kaptRelease
and
kaptDebug
in my gradle file.
🤔 2
w
Is anything generated in the kapt folders? Interesting
d
Yes; you can enable a
verbose
mode for `kapt`: https://kotlinlang.org/docs/reference/kapt.html
In our own case; several months back, this highlighted outrageously and unexpectedly high processing times in Android Data-binding - we ended up engaging with DataBinding authors who fixed the issue in v2 engine.
p
Where would I pass that
verbose
in android studio?
d
In
gradle.properties
add the line:
Copy code
kapt.verbose=true
p
It’s annoying. I use dagger-reflect everywhere in a custom build type and yet it spends a minute of creating empty folders in the buid dir 😉
I added that flag but when running gradle i dont find any specific logs on kapt
d
In Kotlin, you have all the necessary tools to do DI yourself
Without any library
It's just passing dependencies to primary constructor properties
p
I dont want to start a discussion on DI I want to know where the kapt tasks come from if I didnt declare them
👌 1
j
Making HTTP requests is just writing bytes to a Socket. You don't need a library!
🧌 1
👌 2
e
I assume we still need javac even for 100% kotlin code since Dagger generates java code
Sorry, for the offtopic, it doesn’t help with the original question
w
@Paul Woitaschek perhaps you had some tasks up to date? It’s weird that the task runs and no verbose output is printed. Did you try running the relevant assemble task from command line with both verbose kapt and making sure the tasks are run (
./gradlew module:assembleDev -Pkapt.verbose=true --rerun-tasks
)?
p
Nope there is no output on it. But the property itself works, it shows stats on the single module that has an annotation processor running (room)
🤔 1
Im giving up, there are lots of weird things going on. I have only room in a single module and building my highly modularized android application with that single annotation processor takes 7 minutes with 89k lines of kotlin code. The longest task is
app:mergeDevNativeLibs
even though I dont have any native code at all. Even the configuration phase takes 30 seconds 😞
w
Build scan doesn’t give any hints?
That definitely doesn’t seem normal
p
Everything just seems to take very long
g
Windows? Maybe antivirus. Looks like very slow IO Make sense to run gradlr-profiler and check what is going on
Also check GC time of your build
e
Actually GC might be the cause
from gradle I learned that GC timing should be within 4% of the build time
p
And I get less gc time by allocating more memory? (32gb machine)
w
Good place to ask: how to figure out which tasks spawn new processes, and thus would require custom memory configuration?
e
For us it was more memory and less workers
g
https://kotlinlang.slack.com/archives/C0922A726/p1566840184281000?thread_ts=1566807054.253100&cid=C0922A726 First, check time spent on GC (you can find it in build scan), if it below 5% (or even 10%) it will not help. Allocating too much memory also will not help
p
Where do I find the GC time in the build scan?
w
Performance -> Build -> Total garbage collection time
p
30 seconds out of 10:09 minutes
Maybe that whole story of modularized android applications is a lie and it just slows down everything
😀 1
g
30 sec looks fine comparing to build time Anyway, I think you have some problem with IO or something else, it’s just looks too slow or you have a lot of code in each module. I would try on another machine just for reference and if it’s similar tried to profile the build
p
Are there reports on how modularization impacts build time? I always find articles saying that it's great for build time but I never heard of an example where a larger app was refactored from being monolithic to a multi module app. I have like 80 modules and it's a total failure. Even if all tasks are up to date it takes 50 seconds to check that all 1700 tasks created by the Android plugin are up to date.
Let alone that plus configuring for half a minute -.-
w
One notable example I know of is twitter app:

https://www.youtube.com/watch?v=rG6nzrRPMRI

I’m not exactly sure how big their app is, but I think ~100 modules. And their reported build times (from 2 years ago) after migrating to AGP 3.0 which improved performance quite a lot:
g
We have about 150 modules, configuration time after some recent fixes of Kotlin plugin is about 5-8 seconds with warm daemob, not perfect but not so bad
I see that you parallelization is actually not so good, a few modules task run essentially without parallelization most of build time But again, your build really looks unusually slow
e
we have 70 and comparable numbers
w
Comparable to which numbers? Paul's?
p
Why does gradle always configure everything?
If I replace my root
build.gradle
with only a single task:
tasks.register("hello") {}
It throws an exception because all subprojects cant be configured due to the android plugin not applied. But why is it even trying to configure everything? I thought its supposed to do that on demand
g
Configuration happening every time, with or without changes, with warm daemon it a bit better, because of kit and other caching, but by Gradle does configuration every time, even if build file is not changed
Also configuration on demand is very easy to break, it was even discussed to remove this flag (which still experimental). Essentially if you have one single allprojects (on any module) or subprojects block configuration on demand is not working by definition, also not sure that it even suppose to work if you changes task graph
Instant Execution project will help with configuration time, but only when you do not change configs. As I said a few times, try to profile , it's much more helpful than just rant about everything, it's unusually slow from what you show above
e
Gradle has always configuration phase no matter what. Until they might change it. Try to play with bazel or buck
p
And didn't the android plugin changelog say something about task creation avoidance?
For me the android plugin alone creates 14 tasks per module:
compileDebugAndroidTestJavaWithJavac, compileDebugAndroidTestKotlin, compileDebugJavaWithJavac, compileDebugKotlin, compileDebugUnitTestJavaWithJavac, compileDebugUnitTestKotlin, compileDevJavaWithJavac, compileDevKotlin, compileDevUnitTestJavaWithJavac, compileDevUnitTestKotlin, compileReleaseJavaWithJavac, compileReleaseKotlin, compileReleaseUnitTestJavaWithJavac, compileReleaseUnitTestKotlin
g
play with bazel or buck
Don't think that it's good advice if you don't have a person who will support this at least part time. Bazel and buck have some nice features for really big scale, but support of all required tools and just config is not easy Also both of them, to get advantage of fast builds require even more aggressive modularization and carefully managed module dependencies graph
15 tasks per module is not a problem itself, especially with lazy tasks. Essentially you should see how many tasks resolved, not how many existing Poking some completely random characteristics of your build is not really efficient strategy to improve things
j
The Android plugin creates a lot more than 14 per module. It's closer to 100.