Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do import statements in Swift have an associated cost?

Tags:

ios

swift

swift4

Reading the String Manifesto, I saw a paragraph about avoiding the Foundation import when not necessary.

Why is this a concern to the Swift team? Apart from aesthetics and code tidiness, do imports come with a cost?

Could importing unnecessary frameworks impact performance, memory usage, packaged app size or build time?

like image 252
Ferdz Avatar asked Apr 04 '18 13:04

Ferdz


People also ask

What does import do in Swift?

An import declaration allows your code to access symbols that are declared in other files. However, if more than one module declares a function or type with the same name, the compiler may not be able to tell which one you want to call in code.

Do unused imports affect performance?

Do imports affect performance? There is a misconception like unused imports affect the performance of the code. They won't affect the performance of the application in any way. But in some cases, this may cause conflicts between classes in the namespace.

What is an import statement?

An import statement tells the compiler the path of a class or the entire package.

Does import order matter in Swift?

Import order does not matter. If a module relies on other modules, it needs to import them itself.


1 Answers

The page you reference is just saying that they'd like to see more String methods built directly into Swift. Currently some tasks like case-sensitive string comparison require importing Foundation.

Ok I'm going to give the rest of your question a shot. The answer is it depends on what you are importing.

Looking at this answer:

Since Xcode 5, there is a new feature introducing precompiled sources database. Xcode 5 basically compiles all the required frameworks just once, saves builds in the database and that already compiled pieces uses while compiling your code

Also looking at this question:

We see that importing UIKit in every file that uses it is necessary. If the above solution is correct than regardless of how many times UIKit or Foundation is imported it is only compiled once. Thus importing a standard library more than once as no affect on compile time.

However, importing something for the first time would affect compile time because that Library now needs to be compiled when it previously was not needed.

Example if I have to import Foundation in a small Swift program the compile time will be slowed down. When it comes to iOS apps it's basically impossible to not import UIKit which also imports Foundation so I don't think this is worth worrying about since every app will have to compile these libraries as well.

Additionally, we need to look at imports that result from things like Cocoa Pods and Carthage:

Looking at this repo:

There are two ways you can embed third-party dependencies in your projects:

as a source that gets compiled each time you perform a clean build of your project (examples: CocoaPods, git submodules, copy-pasted code, internal libraries in subprojects that the app target depends on) as a prebuilt framework/library (examples: Carthage, static library distributed by a vendor that doesn’t want to provide the source code) CocoaPods being the most popular dependency manager for iOS by design leads to longer compile times, as the source code of 3rd-party libraries in most cases gets compiled each time you perform a clean build. In general you shouldn’t have to do that often but in reality, you do (e.g. because of switching branches, Xcode bugs, etc.).

Carthage, even though it’s harder to use, is a better choice if you care about build times. You build external dependencies only when you change something in the dependency list (add a new framework, update a framework to a newer version, etc.). That may take 5 or 15 minutes to complete but you do it a lot less often than building code embedded with CocoaPods.

Looking at this blog:

We see that there are more precise imports that can be used if one is concerned about compile time. Such as import UIKit.UITableViewController

As far as performance and binary size goes, any unused symbols are already optimized out of the final binary by the Swift compiler. If there’s no reference to it at compile time then it’s removed, meaning that importing a framework but not using particular parts of it shouldn’t have any negative implications.

Another blog states:

In this WWDC 2016 talk, Apple suggests replacing dynamic frameworks with static archives to mitigate this. To take this approach, we rebuilt as many of our dynamic frameworks as possible statically and then merged them into a single monolithic dynamic framework named AutomaticCore.

The difference was dramatic: our app’s launch time was cut in half.

TLDR: It's not worth worrying about importing standard things like Foundation or UIKit they are only compiled once and just about every app uses them so any performance decrease is shared. However, if you are importing third party Frameworks you might want to use a static archive to help with compile time.

like image 66
DoesData Avatar answered Sep 20 '22 21:09

DoesData