mbonnin
11/03/2021, 3:19 PMmacosArm64
, iosArm64
, watchosArm64
, watchosSimulatorArm64
, tvosArm64
, tvosX64
, tvosSimulatorArm64
, ...) our CI build times took a 40min hit š . Is there any chance the compiler could optimize "something" down there as from the distance it looks like it's doing the same thing over and over again?russhwolf
11/03/2021, 3:28 PMmbonnin
11/03/2021, 3:35 PMmbonnin
11/03/2021, 3:36 PMmbonnin
11/03/2021, 3:37 PMankushg
11/03/2021, 5:50 PMlouiscad
11/11/2021, 10:06 AMsvyatoslav.scherbina
11/11/2021, 10:57 AMI think optimizing the Kotlin compiler/linker would nice tooThatās basically what we are doing all the time, see https://youtrack.jetbrains.com/issue/KT-42294
Would sharing any of the linkingĀWhat do you mean by āsharing any of the linkingĀ partsā? Which suggestion do you refer to?parkĀ parts be possible to improve multi-target build times as suggested above?
louiscad
11/11/2021, 11:01 AMsvyatoslav.scherbina
11/11/2021, 12:08 PMLike having another āIRā that the linker could re-use between targets sharing the same API or so... But maybe thatās another range of complexityWhat are ātargets sharing the same APIā?
louiscad
11/11/2021, 12:48 PMmbonnin
11/11/2021, 12:54 PMmbonnin
11/11/2021, 12:55 PMsvyatoslav.scherbina
11/11/2021, 1:45 PMThe 2 ios simulators and iosArm64,They donāt have same API. Even the SDKs in Xcode are different, and some APIs are in fact different. Most of the platform API is the same, but not all.
I have exactly the same code for all the ādarwinā targets and it feels weird that the compiler compiles/links that code N times where N is the number of ādarwinā targetsEven if the code is exactly the same, in some cases it has to be compiled multiple times. For example, consider your Obj-C library has
size_t foo(void);
. And then in Kotlin you have foo() + 1
. Depending on the platform, it can be Int
or Long
.
There are certainly very good reasons it is so but feels weird nonetheless and would be awesome if that use case could be optimized somehowThere is no easy way to optimize this. In any case, right now we are focused on optimizing the scenario of running app or tests on the single target during the development. What is your case? Do you build binaries for all these targets? Why do you need this?
mbonnin
11/11/2021, 1:48 PMmbonnin
11/11/2021, 1:49 PMsize_t
type for an exampleankushg
11/11/2021, 1:50 PMmain
edit: I think we also use debug
instead of release
in PRs because it's significantly fasterrusshwolf
11/11/2021, 1:50 PMmbonnin
11/11/2021, 1:53 PMwe skip some targets on checks that block PRs, and then run a more thorough check on every mergeSame here. We've managed to stay on the Github Action free tier so far but we're really borderline and on busy days the CI can get behind quite a lot.
I think we also useĀOoh interesting š . I'll look into this.Ā instead ofĀdebug
Ā in PRs because it's significantly fasterrelease
It won't catch all API differences, but you could address number size differences by testing one 32-bit and one 64-bit targetIndeed that'd work for some classes of errors, maybe not all
mbonnin
11/11/2021, 1:54 PMlouiscad
11/11/2021, 1:58 PMiosArm64()
, and if only iOS common APIs are used, the output is just shared for the simulator. Otherwise, an incremental compilation recompiles the smallest parts required that are using platform specific APIs (be it from the platform or used libraries).
Same for the scenario of compiling for macosArm64()
with APIs common to iOS/iPadOS, watchOS, tvOS, and macOS of course. That'd be very helpful for platform agnostic libraries.ankushg
11/11/2021, 2:23 PMdebug
variant) are pretty acceptable. The area where K/N build speed hurts us the most is in how long it takes us to actually ship.
In order to have PR turnaround times that make sense, we have to intentionally be less-safe by skipping targets and using debug instead of release -- even though those checks are important to our use cases. When we want to actually consume a new version of our shared library (or fix an error that our less-safe PR checks missed!), it takes quite a while to build a release version because all the link tasks are run serially.
I get that there may not be much to be gained from trying to share intermediate state for these Apple targets -- or if the work needed to represent all of the minor differences between them is too high for too little payoff.
In that case, I think bringing the Kotlin/Native compile and link tasks up-to-date with newer Gradle features like Workers and Configuration Cache would go a long way.
Not only would it drastically improve things for folks like us who have their loops blocked by verifying multiple targets by allowing us to parallelize these steps, but it would also probably improve iteration speeds for common single-target development use cases!svyatoslav.scherbina
11/11/2021, 3:06 PMĀ I think we also useĀYes. While I have your attention, let me also remind you of the document that contains this and probably other useful tips for improving compilation time: https://kotlinlang.org/docs/native-improving-compilation-time.html. @mbonninĀ instead ofĀdebug
Ā in PRs because itās significantly fasterrelease
Iām building a lib so it needs to ship all the targetsDo you have any binaries declared? Is it possible that you build not only klibs, but also a lot of binaries? @louiscad
Could we imagine having the compiler know/track the API differences, to it can only recompile whatās needed for the other but similar targets?Although one could imaging having this, we are not working on this at the moment, and donāt have short-term plans for this. And this would require quite a lot of work. After all, we still have more doable things to optimize.
For example, itād start by building forĀThe output canāt be just shared for the simulator, because these are different native targets which require different machine code generated. @ankushg, and if only iOS common APIs are used, the output is just shared for the simulator.iosArm64()
In that case, I think bringing the Kotlin/Native compile and link tasks up-to-date with newer Gradle features likeĀ WorkersĀ andĀ Configuration CacheĀ would go aĀ longĀ way.This is way more feasible and implementable. Unfortunately, all folks working on Gradle support are somewhat busy with stabilizing things for KMM Beta, so I canāt promise you any ETA here. But I personally consider this as one of the next steps in improving the compilation time.
louiscad
11/11/2021, 3:09 PMThe output canāt be just shared for the simulator, because these are different native targets which require different machine code generated.Not when it comes to the Apple Silicon simulator though?
svyatoslav.scherbina
11/11/2021, 3:15 PMNot when it comes to the Apple Silicon simulator though?In this case too. iOS simulator on Apple Silicon is different from iOS device with arm64. It might be possible to reuse something, but the binaries still arenāt identical. Otherwise we wouldnāt have to add a whole bunch of new targets for Apple Silicon š See e.g. https://youtrack.jetbrains.com/issue/KT-43667
mbonnin
11/11/2021, 3:21 PMDo you have any binaries declared
I'll double check but my understanding is that tests will need linking anyways so that will need to be linked ?
svyatoslav.scherbina
11/11/2021, 3:59 PMbuild
, assemble
or check
. But please ensure that you donāt run these tasks in other way.
Generally, it might be a good idea to start investigation with taking a look at Gradle build scan.ankushg
11/11/2021, 4:14 PMDo you have any binaries declared? Is it possible that you build not only klibs, but also a lot of binaries?Many folks (like us and maybe @mbonnin š) are intentionally building binaries like XCFrameworks as part of their CI steps, because the projects are intended to eventually be consumed from Swift/Obj-C codebases, outside of KMP. Or sometimes, the library also includes samples that folks want to make sure can compile their binaries.
> In that case, I think bringing the Kotlin/Native compile and link tasks up-to-date with newer Gradle features likeĀ WorkersĀ andĀ Configuration CacheĀ would go aĀ longĀ way.
This is way more feasible and implementable.
Unfortunately, all folks working on Gradle support are somewhat busy with stabilizing things for KMM Beta, so I canāt promise you any ETA here. But I personally consider this as one of the next steps in improving the compilation time.This is good to hear! Hopefully it's not too complicated, because it'll be a big help for us!
Paul Woitaschek
12/08/2021, 9:54 PMArkadii Ivanov
01/27/2022, 9:58 AM