If this post is helpful for you, consider donating to my patreon. It helps me produce better tutorials, faster. Visit my Patreon.

Become a Patron!

# List Comprehensions and Performance With Swift

This post written by Veronica Ray
Veronica Ray is a software engineer at LinkedIn. She honed her functional programming chops in Scala and is excited about developing on iOS with Swift. Once she rode her bike between two moose. Follow her on Medium and Twitter: @nerdonica.

This post written on August 15, 2015 to be compatible with Xcode 6 and Swift 1.2

List comprehensions provide a concise way to create lists. You can accomplish list comprehension-like operations in Swift even though list comprehensions are not mentioned in the Swift language guide.

Say you want to create a list of squares, like:

``var squares = [Int]()for x in 1..<10 {    squares.append(x*x)}``

In Python you could use a list comprehension instead

``squares = [x**2 for x in range(10)]``

In Swift you can do

``let squares = Array(map(1..<10) { \$0 * \$0 })``

To get the sum of all the elements in the list you could do this

``var sum = 0for square in squares {    sum = sum + square}``

Or use the reduce function

``let sum = squares.reduce(0, { \$0 + \$1 })``

Like list comprehensions in some other languages, you can use any Sequence or Collection as the input, not just a Range.

You can use map/reduce/filter/stride depending on what kind of list you are trying to create.

The two main perks of list comprehensions are conciseness and being able to generate faster bitcode.

My imitation list comprehension was more concise. I was curious whether it would also generate faster bitcode.

This article showed me how to analyze Swift assembly code using Hopper, an OSX and Linux disassembler. You can try Hopper for free without buying a license.

The code snippets without list comprehensions and with the imitation list comprehensions generated the same assembly code.

Since both snippets created the same assembly code I assumed their execution time would be the same. We can demontrate this by measuring the execution of our program using XCTest.

My test for the code snippet with no list comprehension

``func testNoListComprehensionPerformance() {    self.measureBlock() {        var squares = [Int]()        for x in 1...5 {            squares.append(x)        }    }}``

The relevant output

Test Case '-[speedTestTests.speedTestTests testNoListComprehensionPerformance]' started.

:0: Test Case '-[speedTestTests.speedTestTests testNoListComprehensionPerformance]' measured [Time, seconds] average: 0.000, relative standard deviation: 236.965%, values: [0.000154, 0.000005, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004, 0.000004], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[speedTestTests.speedTestTests testNoListComprehensionPerformance]' passed (0.262 seconds).

My test for the code snippet with the imitation list comprehension

Test Case '-[speedTestTests.speedTestTests testSortaListComprehensionPerformance]' started.

:0: Test Case '-[speedTestTests.speedTestTests testSortaListComprehensionPerformance]' measured [Time, seconds] average: 0.000, relative standard deviation: 160.077%, values: [0.000045, 0.000005, 0.000004, 0.000003, 0.000003, 0.000003, 0.000003, 0.000004, 0.000003, 0.000003], performanceMetricID:com.apple.XCTPerformanceMetric_WallClockTime, baselineName: "", baselineAverage: , maxPercentRegression: 10.000%, maxPercentRelativeStandardDeviation: 10.000%, maxRegression: 0.100, maxStandardDeviation: 0.100
Test Case '-[speedTestTests.speedTestTests testSortaListComprehensionPerformance]' passed (0.255 seconds).

On average they only differ by only 0.007 seconds.

The coolest application of list comprehensions I've seen is in a spelling corrector. Airspeed Velocity wrote a Swift version of Peter Norvig's Python spelling corrector.

Conciseness is the main benefit of using list comprehension-like operations in Swift. Paul Graham wrote a great essay about how conciseness in programming languages is power. Since each programmer can only write a certain number of lines of code per day, you can accomplish more each day if you can accomplish more in the same number of lines. This power also makes you rethink what programs are possible. In a more verbose language this spelling corrector example could have seemed like an overwhelming project. I love how how something as technically complex and mysterious as a spelling corrector can be expressed in so few lines of code in Swift.

Did this tutorial help you?

Your support on Patreon allows me to make better tutorials more often.

Subscribe via RSS