I was reading Test-Driven iOS Development with Swift , at some point the author provided 2 different implementations for the same method as follows

number of vowels in string

Note: the author’s intent was about breaking changes and not performance.

“we now don’t have to worry about breaking the feature when changing the implementation.”

Excerpt From: Dr. Dominik Hauser. “Test-Driven iOS Development with Swift.” iBooks.

I really liked the idea of testing the performance of two different implementations (it was outside the scope of the book) so I decided to test various implementations and see how far we can reduce the time required to achieve the same result.

I created an Xcode project as follows

Xcode project configuration

Inside the viewController.swift I wrote both implementations that are previously mentioned, I also prefixed the second one by reduce_ in order to distinguish them.

viewController.swift

Inside the PerformanceTests.swift, we have the PerformanceTests class where I removed everything and replaced its content as follows

PerformanceTests.swift

You can get the full project from here.

First we declare two new properties: string defines a string to use in the test, and viewController an instance of ViewController. Then we have to make sure that our implementations of the Methods return a correct number , i.e. returning 167 which is the number of vowels in our string. We can do that by implementing testReduce() and testFastEnumeration(). What matters more to us is implementing testPerformanceFastEnumeration() and testPerformanceReduce() where we call self.measure block. The code in measureBlock is called several times, and the average duration is measured. As you can see I am running the code 1000 times in the measureBlock to get a reasonable time. So let’s hit cmd-U and see the result of our implementation.

test result

The green diamond with a checkmark on the left-hand side of the editor indicates that the tests are passed. Also the enumeration performance test is slightly better than the reduce performance (1.276 vs 1294).

Now let’s provide a new implementation inside the viewController class

Fast enumeration with Where clause

By changing only the check to a where clause, can we get better a performance ? let’s try it

Fast enumeration with Where clause test result

as you can see the performance has slightly improved.

let’s try another Implementation by accessing the unsafeBufferPointer of the vowels array

with unsafe buffer pointer

for every character in the string we can check the vowels from the bufferPointer rather than from the vowels array itself.

let’s see the performance result

with unssafe buffer pointer test result

BOOM 0.573 sec is less than half of the time from the first run. So by accessing the array’s contiguous storage we gain so mush performance.

Do you know that we can enhance the last method performance? Yes. How? good question. it is a simple modification, just replace

for aCharacter in bufferPointer

by

for index in bufferPointer.startIndex..<bufferPointer.endIndex

what about the test result ? let’s see

BOOM BOOM 0.278 sec Can you believe that ? it is twice as faster than the previous implementation.

You probably guessed what will come next. Let’s try to read both the string and the vowels using unsafeBufferPointer as follows

and the test result, as expected, will be better

As you can see, the performance test is better by ~16%

Can we do better ? let’s see

What if we divide the string into smaller chunks and check them in parallel as follows

Our performance test result is similar to the previous one with a slight improvement.

From ~1.2 sec to ~0.220 sec performing the same task.

I hope you enjoyed the article. If you have a faster way to check the vowels let me know about it in the comments, may it be by using regular expression or a whole new algorithm.