firebase-ios-sdk icon indicating copy to clipboard operation
firebase-ios-sdk copied to clipboard

Extremely slow compile time of Objective-C files and dependencies

Open Kaspik opened this issue 2 years ago • 16 comments

[REQUIRED] Step 1: Describe your environment

  • Xcode version: 14.0 Beta 1
  • Firebase SDK version: 9.1.0
  • Installation method: Swift Package Manager
  • Firebase Component: Promises - dependency, Crashlytics
  • Target platform(s): iOS

[REQUIRED] Step 2: Describe the problem

When building the app in new Xcode 14.0 Beta 1 - new Build Timeline is available to show you the build and compile times. Firebase and mainly it's dependencies we didn't choose to use are the biggest slowdown of our compile times. (see an attachment)

It would be nice to either:

  1. Improve compile time of the dependency
  2. Try to find a way how to release the framework without these dependencies

Build environment: MacBook Pro M1 Max, 32GB, Xcode 14.0 Beta 1, iOS 16 beta 1 simulator of iPhone 13 Pro

Screenshot 2022-06-07 at 15 50 13

Steps to reproduce:

Include Crashlytics + Analytics + Messaging in your project via SPM and run Build (Compile) with new Xcode - then check the Build Timeline.

Additional notes

I did open an issue in the dependency itself (promises), but wanted to cross-link it here for shared knowledge - but it's also Crashlytics problem.

I do think this is related to the new and still better Swift-optimized compiler and build system, but maybe it's the right time to migrate relevant Objective-C code to Swift too?

Let me know if I can be helpful here somehow. Thanks for looking into this!

Kaspik avatar Jun 07 '22 14:06 Kaspik

I found a few problems with this issue:

  • I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
  • This issue does not seem to follow the issue template. Make sure you provide all the required information.

google-oss-bot avatar Jun 07 '22 14:06 google-oss-bot

Thanks the for the report! We're keen to dig into this more - one strange thing in particular is GULNSData+zlib.m seemingly taking 13+ seconds when it's less than 200 lines of code: https://github.com/google/GoogleUtilities/blob/main/GoogleUtilities/NSData%2Bzlib/GULNSData%2Bzlib.m

Hunch: maybe it has to do with the ObjC categories, as FBLPromises also is longer than expected.

ryanwilson avatar Jun 07 '22 17:06 ryanwilson

It's importing zlib which is probably little big bigger, right?

Kaspik avatar Jun 07 '22 17:06 Kaspik

Okay I ran it locally and saw really strange results. My hunch: some of these long times include waiting time until the next file can build. Example: dummy.m took 439 seconds to build... which is an empty file. I'll try to dig into the WWDC sessions to see if this is explained further, or maybe it's time to file some Feedback.

My build: My Local Build

ryanwilson avatar Jun 07 '22 17:06 ryanwilson

That's really long time. 😄 I'll keep an eye on this and the files that take longer than expected. Thanks for digging into this, every build time improvement is huge improvement for everyone!

Kaspik avatar Jun 07 '22 17:06 Kaspik

Thanks for digging into this, every build time improvement is huge improvement for everyone!

Sure thing, thanks again for the report! We're excited to see how we can improve our build times.

ryanwilson avatar Jun 07 '22 17:06 ryanwilson

Hey @Kaspik, I built PromisesObjC with clang's -ftime-trace and found that all of the files that took a while in your screenshot built in ~100ms. Screen Shot 2022-06-08 at 3 37 22 PM

I did this via CocoaPods by setting -ftime-trace in the Other C Flags build setting of the generated Pods project, and then examining the generated json in chrome://tracing. The build time trace can be found in

DerivedData/${PROJECT}/Build/Intermediates.noindex/Pods.build/${DESTINATION}/PromisesObjC.build/Objects-normal/${ARCH}/${FILENAME}.json

Where in my case PROJECT was the FirebaseUI sample project, DESTINATION was Debug-iphonesimulator, ARCH was x86_64, and FILENAME was FBLPromise+Race.

It does seem like Xcode 14 is including waiting time as build time for files, which is resulting in inaccurate graphs.

morganchen12 avatar Jun 08 '22 22:06 morganchen12

Hey @morganchen12, interesting!

FILENAME was FBLPromise+Race - so did you compile just the one file, or the project itself completely? And did you try that without CocoaPods but via SPM?

Kaspik avatar Jun 09 '22 10:06 Kaspik

I compiled the entire project (performance traces are generated per-file). The package manager should not affect the compile times, but I can try again with SPM if you'd like.

morganchen12 avatar Jun 09 '22 17:06 morganchen12

@Kaspik Thumbs up for raising this. @ryanwilson Any updates? We're seeing the same behavior. The slowest parts are FBLPromises, GoogleDataTransport, and FirebaseCrashlytics. Slow compile times can be also observed with GoogleSignIn dependency. Screenshot 2022-06-22 at 14 44 31

Let me know if I can help somehow.

MartinStrambach avatar Jun 22 '22 12:06 MartinStrambach

@MartinStrambach, have you tried compiling your project with the -ftime-trace flag to identify bottlenecks in the built dependencies? Our investigation suggests Xcode is including time spent waiting to compile a file as total compile time, which is resulting in misleading build times for some dependencies.

morganchen12 avatar Jun 22 '22 16:06 morganchen12

@morganchen12 It probably works like that, but it behaves the same even if you create an empty project and link only Firebase Analytics. If you add Crashlytics and Performance it takes more than a minute to compile only these 3 dependencies. IMO, the issue is labeled incorrectly. It hasn't been introduced in Xcode 14. You can only visualize the issue there.

MartinStrambach avatar Jun 23 '22 10:06 MartinStrambach

I'm seeing these strange things across other hybrid project which objective-c compiling is super slow.

As we now have P cores/E cores on apple silicons and they have shockingly performance differences, I'm suspecting that Xcode will strategically assign objective-c source code to E cores to compile for some reason.

I agree with @MartinStrambach that this strategy could have been introduced for very long but we couldn't see it until Xcode14

dingtianran avatar Jun 28 '22 00:06 dingtianran

@dingtianran The same happens on Intel macs as well, not just Apple Silicons.

MartinStrambach avatar Aug 09 '22 17:08 MartinStrambach

Is this still an issue with the Xcode 14 GA?

paulb777 avatar Dec 01 '22 23:12 paulb777

It got better! But yes, it's still an issue as it's still the slowest compiled files that in total (together even in parallel) make a big chunk of compile time.

Promises, GoogleDataTransport, Crashlytics - some files take more than 2 seconds (some even 5 seconds, but luckily not 10 as it was in the beta).

GDTCORUploadCoordinator.m 1.8 seconds
GDTCORTransformer.m 1.9 seconds
GDTCORTransport.m 2.1 seconds
FIRCrashlytics.m 2.3 seconds
Screenshot 2022-12-02 at 10 27 38

Overall, I don't think there is much to improve or do except really try to port those files into swift or divide them into separate modules / less cross-dependent modules. Not sure where the Swift rewrite lays down at your roadmap, but curious to hear your thoughts and ideas :)

Kaspik avatar Dec 02 '22 09:12 Kaspik

Going to close since there's not a clear action. We are gradually migrating our implementations from Objective C to Swift.

paulb777 avatar Apr 05 '23 04:04 paulb777