Win a ticket for the ARCtic Conference. Join here for free.
Give your simulator superpowers

RocketSim: An Essential Developer Tool
as recommended by Apple

Measure the performance of code in Swift

It’s important in any type of programming language to know how to measure the performance of code as there are many different ways to write solutions and not every solution is as performant as the other. If a piece of code turns out to be slow in, for example, the results of the Time Profiler in instruments, you need a way to improve it.

I’m curious, what do you think would perform better?

Looking at this tweet:

Improvement starts with measuring the baseline so you can actually tell if a new piece of code performs better. A good way to do this is by making use of the measure method available in XCTest. You can make use of this method in three different ways:

  • Writing a unit test in an Xcode project
  • Writing a unit test in a Playground
  • Writing a unit test and execute it in the terminal

You might be surprised, but the results over every method are not the same.

Although Playgrounds are easy to set up and give you results very quickly, it’s way less performant.

Stay updated with the best of Swift & SwiftUI

Join over 20,006 Swift developers in SwiftLee Weekly for exclusive tips and updates. Don’t miss out – subscribe now:

You can always unsubscribe, no hard feelings.

The code we’re going to measure

In this example, we’re going to measure the performance fetching even numbers from a big collection of numbers. In one scenario we make use of a for loop combined with an if statement. In the other scenario, we’re going to make use of a filter combined with a for each loop.

import XCTest

class PerformanceTests: XCTestCase {

    lazy var testData: [Int] = {
        return (0..<100000).map { Int($0) }
    }()

    func testForEachLoop() {
        measure {
            var evenNumbers: [Int] = []
            testData.filter { number in number % 2 == 0}.forEach { number in evenNumbers.append(number) }
        }
    }

    func testForLoop() {
        measure {
            var evenNumbers: [Int] = []
              for number in testData {
                if number % 2 == 0 {
                    evenNumbers.append(number)
                }
            }
        }
    }
}

/// In case of a Playground:
PerformanceTests.defaultTestSuite.run()

Running test code from the terminal

Although running this code from a Playground or Xcode project should be fairly simple, running it from the terminal is a bit less familiar for most of us.

The code needs to be compiled first before it can be executed from the terminal. You can do this by pointing to your Xcode installation combined with the swiftc command.

swiftc -Onone -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks/ -Xlinker -rpath -Xlinker /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -lswiftCore Performance.swift -o performance

Performance.swift is our input filename and -o performance is our output filename. After executing this line in your terminal you can execute the Swift file by using ./performance.

The results

Type of codeXcode Unit TestPlaygroundTerminal
For loop if0.02626.0520.030
Filter forEach0.0432.1160.047

We can conclude that measuring the performance of code can be done is by making use of unit tests inside an Xcode project. Although Playgrounds are easy to set up and give you results very quickly, it’s way less performant.

Reasons for the Playground to be slow is related to the UI updates to be done as pointed out by Paul.

Both Terminal and unit tests in an Xcode project give more or less the same results. Taking into account the overhead of running tests in the Terminal the best way to measure the performance of a piece of code is by making use of unit tests in a normal Xcode project.

 
Antoine van der Lee

Written by

Antoine van der Lee

iOS Developer since 2010, former Staff iOS Engineer at WeTransfer and currently full-time Indie Developer & Founder at SwiftLee. Writing a new blog post every week related to Swift, iOS and Xcode. Regular speaker and workshop host.

Are you ready to

Turn your side projects into independence?

Learn my proven steps to transform your passion into profit.