9

I notice there are two settings of optimization in the project settings :

  • Single-File Optimization
  • Whole Module Optimization

enter image description here

What's the difference? And which one should we choose under what circumstances?

Yuchen
  • 30,852
  • 26
  • 164
  • 234
  • briefly: _single-file_ optimisation is optimising the files individually while the _whole-module_ optimisation evaluates your entire project and makes the optimisation based on project's structure. – holex Dec 27 '17 at 21:04
  • 1
    See WWDC 2015 video [Optimizing Swift Performance](https://developer.apple.com/videos/play/wwdc2015/409/). Or see 2016 videos [Understanding Swift Performance](https://developer.apple.com/videos/play/wwdc2016/416/) or [What's New in Swift](https://developer.apple.com/videos/play/wwdc2016/402/) in which they talk about enhancements to whole module optimization. – Rob Dec 27 '17 at 21:07
  • In answer to your question of which you should choose under certain circumstances, it's a tradeoff between compilation time and whether you want the benefits of whole module optimization or not. Personally, I use no optimizations on debug builds (enjoy robust Swift safety features, make it easier to debug and diagnose problems) and whole module optimization on release builds. – Rob Dec 27 '17 at 21:14

2 Answers2

18

Single-file Optimization

This optimization mode has the compiler run one frontend instance per file in your program. It runs optimizations on each file separately, loading as little information as it can from other files in the project.

Pros

  • When doing incremental compilation, the compiler doesn't have to recompile your whole project, and can instead recompile just the files that have changed or rely on files that have changed
  • The compiler runs one instance per file, so on a computer with multiple cores, it can compile faster

Cons

  • Some optimizations will not be performed if the content that's being optimized spans multiple files
  • The compiler does have to get some information out of other files so it may repeat this work more times than necessary (if 6 files reference one other file, that file may have some work performed on it 6 times when only 1 was needed)

Whole-Module Optimization

This optimization mode will run one frontend instance for your whole module. It runs optimizations on all the files at once.

Pros

  • This will perform the maximum optimizations that the swift compiler can perform
  • Performs less redundant work than Single-file Optimization

Cons

  • This will only use one CPU core to run all the swift-specific optimizations on your code. This means that a multi-core computer will not be fully utilized compiling your code
  • In incremental compilation, your whole module will still have to be recompiled every time

What to Use

For debug builds, I highly recommend completely disabling optimizations. This will make stepping through your code in the debugger more predictable and will make build times shorter. If you really need optimizations, you should probably go with single-file for the better incremental compilation times.

For release builds, I recommend using whole-module optimization, as it can perform more optimizations than single-file optimization.

TellowKrinkle
  • 351
  • 3
  • 5
1

Optimization Level(SWIFT_OPTIMIZATION_LEVEL) -O vs -O -whole-module-optimization

swiftc command

definitions

  • Driver - root process which decide which exactly file should be compiled and starts child process(jobs) for compiling, assembling and linking
    • Frontend Job(swift -frontend) - is responsible for compilation
    • ld job - static linking and other jobs

compiling

  • Primary-file - compiling single file. An advantage is incremental compilation and parrallelizing. A disadvantage is that in any case every frontend job has to read all files in module before starting
    • single-file - one frontend job for one file
    • batch(-enable-batch-mode) - one frontend job for one CPU
  • whole-module optimization(WMO)(-wmo) - one frontend job for one module. An advantage is good optimizations results which are reflected on runtime. A disadvantage is no incremental build and worse parrallelism

Optimization

-O Single-File compilation - compiler operated by single file(e.g. .swift). It means that compiled doesn't know any other information out of this file. That is why compilation can be paralleled and incremented(don't compile file and it's dependencies were not changed)

-O -whole-module-optimization - compiler operated by whole module. It is next level of optimizations. From Xcode v8 it is by default for new projects and SPM for release. On this level compiler has much more information about calls. Compilation consists of two big parts(SIL optimizer(1/3 time) and LLVM(2/3 tile)). SIL optimizer is a bottle neck and can not be paralleled and incremented but LLVM can

Optimizations examples:

  • inline function - executable code over function call
  • function specialization - for example concrete function(new function version) over generic function
  • reference counting operations
  • remove unnecessary functions
  • Ordering[About]

Also you can get next warning during debugging with optimizations

Project was compiled with optimization — stepping may behave oddly; variables may not be available.

It is because of additional parameter fast which is passed. As a workaround you are able to use -Onone and add user-defined settings as SWIFT_WHOLE_MODULE_OPTIMIZATION=YES

Compilation Mode(SWIFT_COMPILATION_MODE)

  • Incremental - by default for debug - compiles out of date files
  • Whole Module - by default for release

Paralelize

Edit Scheme -> Build -> Parallel Build
yoAlex5
  • 29,217
  • 8
  • 193
  • 205