quapona technologies

In this blog post and in future series, we will measure the performance of the recently released Swift compiler and it's runtime under Linux. We will compare selected algorithms written in C/C++ against their Swift counterpart.

Swift is nowadays apparently the most interesting programming language for iOs and Mac developers. Since it's release in 2014, it gains a lot of attraction. Now - in 12/2015 - the language is on par with Objective-C in the Tiobe popularity index. In this index Objective-C has the 14. and Swift the 15. place. This leaves pleanty room for improvements.

However, through its modern language concepts and its safe by design principle, Swift may gain more attraction to developers outside the Apple ecosystem. One important step into the right direction was made by Apple itself - the company has released Swift and additional libraries under the Apache open source license.

Ususally developers cannot be convinced by concepts and concerned with


1. Prequisites

Albeit we use Debian GNU/Linux Stretch (Testing) for our investigation, all commands shown below should also work under Ubuntu, Ubuntu LTS and other *dpkg* centric distributions.

For further informations please consider Apple's GitHub repository https://github.com/apple/swift

1.1 Installing build environment

Installing the build packages

sudo apt-get install git cmake ninja-build clang uuid-dev libicu-dev icu-devtools libbsd-dev libedit-dev libxml2-dev libsqlite3-dev swig libpython-dev libncurses5-dev pkg-config

Updating the clang compiler

sudo apt-get install clang-3.6
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100

1.2 Fetching sources

Create a directory where the swift sources and the build directory can be reside.

cd ~
mkdir swift_source_root
cd swift_source_root
git clone https://github.com/apple/swift.git swift
git clone https://github.com/apple/swift-llvm.git llvm
git clone https://github.com/apple/swift-clang.git clang
git clone https://github.com/apple/swift-lldb.git lldb
git clone https://github.com/apple/swift-cmark.git cmark
git clone https://github.com/apple/swift-llbuild.git llbuild
git clone https://github.com/apple/swift-package-manager.git swiftpm
git clone https://github.com/apple/swift-corelibs-xctest.git
git clone https://github.com/apple/swift-corelibs-foundation.git

1.3 Building Swift

Swift comes with a helpful build script that compiles everything for us. The 'build-script' expects the sources to be laid out in the following way:

/lldb (optional)
/llbuild (optional)
/swiftpm (optional, requires llbuild)
/swift-corelibs-xctest (optional)
/swift-corelibs-foundation (optional)

The source root can be set manually by defining a environemtal varibale, e.g.

export SWIFT_SOURCE_ROOT = "$(HOME)/swift_source_root"

Since we are in the source root directory, the script automatically detects the source root. Therefore we can directly invoke the build without setting this directory

[~/swift_source_root]$ ./swift/utils/build-script -R -t

The parameters -R and -t defines to build the release version of everything. To compile for debug (default), omit the -R parameter.

[~/swift_source_root]$ ./swift/utils/build-script -t

For other build configurations conslut build-script's help.

./swift/utils/build-script -h


2. Benchmarks

In order to get a qualified statement of Swift vs. C performance, we have implemented different scenarios.

2.1 Fibonacci

The first benchmark we've implemented is the computation of a Fibonacci number.
We have implemented the recursive version of the algorithm; therefore do not expect performance wonders here - the iterative version will be much faster. For our purpose, however, it is sufficient, because it contains a lot of memory operations and function calls. Thus, this version allows us to make a statement about the performance when a lot of method are called.

Swift implementation to compute a Fibonacci number (**Fib.swift**)

func fib(number : UInt) -> UInt
if (number <= 2) {
return number;
let a = fib(number - 1);
let b = fib(number - 2);
return a + b;

func main() { var number : UInt = 0; for argument in Process.arguments { let num:UInt? = UInt(argument) if num != nil { number = num!; } } let result = fib(number); print("fib(\(number)) = \(result)"); } main();

C implementation to compute a Fibonacci number (**Fib.c**)

#include <stdio.h>
#include <stdlib.h>

unsigned long fib(unsigned long number)
{ if (number <= 2) return number;
unsigned long a = fib(number-1);
unsigned long b = fib(number-2);
return a + b;

int main(int argc, char **argp)
{ unsigned long number = 0;
for (int i = 0; i < argc; i++) {
number = atoi( argp[i] );

unsigned long result = fib(number);
printf("fib(%lu) = %lu\n", number, result);

return 0;

The following compilers were used:

gcc 5.2.1
clang 3.8.0
Swift 2.2-dev

To compile the examples, use the following commands:

gcc -O3 Fib.c -o Fib.gcc
clang -O3 Fib.c -o Fib.clang
swiftc -O Fib.swift

The run time of the programs can be measured with the ususal Linux "time" command. For example, to measure the time to compute the 49'th Fibonacci number you can issue:

time ./Fib.gcc 49
fib(49) = 12586269025
real 0m10.026s
user 0m10.040s sys 0m0.000s

time ./Fib.clang 49
fib(49) = 12586269025
real 0m21.194s
user 0m21.228s
sys 0m0.000s

time ./Fib 49
fib(49) = 12586269025
real 0m17.893s
user 0m17.920s
sys 0m0.004s

As you can see in the results for the Fibonacci workload above, the new gcc 5.2 outperforms it's competitors by approximatly the factor of 2. This is no wonder, because a lot of work was spend in the optimization over the years of it's development.

The suprising result here is that Swift outperforms clang. One would have expected that clang/LLVM should beat Swift in terms of function invocation, because Swift has inherended a dynamic invocation technique form Objective-C. The results here clearly shown that this principle performance drawback did not occur in Swift 2.0.



In a future article, we will investigate the Swift compiler and the runtime in more detail with additional benchmarks. Stay tuned!

Kommentare powered by CComment

Beitrag teilen