Swift Build Time Too Long When the Configuration Is 'Release'

Swift app only performing reasonably when built for Xcode's Time Profiler?

You were building the app in Debug mode instead of Release mode. Debug mode is much easier to debug, but release mode generates faster code.


When building for Debug mode, the compiler inserts special debug symbols that help the debugger. I once tried to debug an app in Release mode and the debugger couldn't even find my variables. Release mode not only doesn't include those symbols, but it also optimizes your app, generating a binary that is much smaller and faster.


Here's how to switch between Debug and Release mode:

  • Click on your scheme in the top-left corner of Xcode.

Click on your scheme in the top-left corner of Xcode.

  • Select "Edit Scheme..."

Select "Edit Scheme..."

  • Click on the "Build Configuration" dropdown.

Click on the "Build Configuration" dropdown.

  • Change the build configuration to Release.

Do I really need to provide alt text here?

  • Rebuild your project.

(I am not providing an image here because I assume you know how to rebuild your project.)

Build time is too long in Xcode 8.3 with swift 3 in particular file

I tried debugging your issue. This is what I found out:

if let pdfData = data as? CFData {

}

The above line for casting object of type Data to CFData is where it's taking too much time to build.

Replacing that with the following piece of code significantly reduces your build time.

let pdfNsData: NSData = NSData(data: data) // convert `Data` to `NSData`

if let cfPdfData: CFData = pdfNsData as? CFData {
// cast `NSData` to `CFData`

}

NSData and CFData are toll-free bridged.

Please let me know if there's any doubt

iOS App is 20x slower after building with Xcode 11

After I rewrote the SIMD-heavy Swift codebase to Objective-C, the old performance was restored. Objective-C thankfully still uses the good old SIMD data types without pointless wrappers.

The performance correlates with changes in Swift's implementation of SIMD. In Xcode 10.1 and older, Swift used built-in SIMD data types. With Xcode 10.2 (and newer), Apple added useless Object-Oriented wrapper for SIMD data types (e.g. float3 is typealias for SIMD4<Float>) and operations and didn't even bother to test the performance, which made my code more than 20x slower.

Sometimes you just need speed, don't force Protocol-oriented design where it doesn't belong to.

It doesn't matter if you choose to use Swift 4 or target iOS 12 in Xcode 10.2 and newer, you'll still get the same, bad SIMD performance.

TL;DR: Apple messed-up pre-Swift-5 SIMD levels of performance in Xcode 10.2 and newer. Port your SIMD-heavy code to Objective-C to get good old levels performance (>20x faster in my case). Let's hope Apple doesn't touch Objective-C or we're soon going to write in Neon assembly to get decent performance...

Xcode 10 iOS app build, hidden task takes most of build time

I have this same issue and after a lot of investigation I have determined that whatever it is doing, it is based on the number of swift source files you have.

The Root Cause

In the 2018 wwdc talk about the Xcode build system the presenter says (searchable in the transcript of the video):

What this means is that unlike Clang, when compiling one Swift file, the compiler will parse all the other Swift files in the target.

So even if/though the incremental build only needs to recompile a single file, it still parses every other swift file.

Our project has over 2000 swift source files and we are seeing incremental build times of 3+ minutes for recompiling a single independent file.

Testing to prove the root cause

Because hearing it in a WWDC talk is not enough, I did the following to test it myself:

  1. Created a new project
  2. Tested incremental build times for nearly empty project, changing a single file

    • Incremental build completes nearly instantaneously (< 1-2 seconds)
  3. Used a script to generate 2,000 swift files, each containing a simple struct with a unique name, 2 variables, and a simple function. There are no dependencies between any of the files.
  4. Add the directory containing the 2,000 new swift files to the project and complete a full build.
  5. Test incremental build times again for a single file

    • Incremental build time took more than 1 minute

In my testing, the complexity of the contents of the additional swift files does not seem to be significant, only the number of files.

The Solution - Modularization/Frameworks

Separate your app in to smaller frameworks to reduce the number of swift source files in each target.

This is a decent guide showing steps on how to go about this if you don't already know how.

In my test case above, I created a new framework and moved the 2,000 swift files into the framework and then tested incremental build times in the original project (importing the framework) and the build times were back to < 1-2 seconds. Of course doing an incremental build inside of the framework would still be slow, but ideally you would split the project into many and smaller frameworks so that each will have faster incremental build times.

Not the Solution - Merging Files

If the problem is the number of files, why not merge a bunch of files to reduce the number? Because it will likely result in slower incremental builds.

According to 2018 WWDC's Building Faster in Xcode:

Swift's dependency model is based around files

This relates to our current problem because it means that any change to a file (except for changes to function body contents only) will cause recompilation for any file that depends on ANYTHING in the changed file.

If you merge many types into a single file, it will result in more code getting recompiled on incremental builds if any of the changes touch the large file or any of its dependencies. It will also increase the number dependents the large file has, making it so all of them get recompiled if ANY of the types in the large file are modified.



Related Topics



Leave a reply



Submit