Created
January 3, 2017 15:41
-
-
Save mathewsanders/c4c43915c5e1c13e8fe3b912bf4c27d1 to your computer and use it in GitHub Desktop.
Benchmark substring speed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// SubstringTests.swift | |
// SubstringTests | |
// | |
// Created by Mat on 1/3/17. | |
// Copyright © 2017 Mat. All rights reserved. | |
// | |
import XCTest | |
class SubstringTests: XCTestCase { | |
let tests = "Hello, tests" | |
let empty = "" | |
let start = 1 | |
let end = 10 | |
let itrations = 1000000 | |
// benchmark substring | |
func testPerformanceBaseline() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.tests.substringBaseline(start: self.start, end: self.end) | |
} | |
} | |
} | |
func testPerformanceAlternative() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.tests.substringAlternative(start: self.start, end: self.end) | |
} | |
} | |
} | |
func testPerformanceUTF16() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.tests.substringUTF16(start: self.start, end: self.end) | |
} | |
} | |
} | |
func testPerformanceUTF16Nil() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.tests.substringUTF16Nil(start: self.start, end: self.end) | |
} | |
} | |
} | |
// benchmark early exit | |
func testPerformanceBaselineEmptyString() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.empty.substringBaseline(start: self.start, end: self.end) | |
} | |
} | |
} | |
func testPerformanceAlternativeEmptyString() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.empty.substringAlternative(start: self.start, end: self.end) | |
} | |
} | |
} | |
func testPerformanceUTF16EmptyString() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.empty.substringUTF16(start: self.start, end: self.end) | |
} | |
} | |
} | |
func testPerformanceUTF16NilEmptyString() { | |
self.measure { | |
for _ in 0..<self.itrations { | |
let _ = self.empty.substringUTF16Nil(start: self.start, end: self.end) | |
} | |
} | |
} | |
} | |
// "hello tests".substring(1,10) | |
// baseline -> 1.151s (2% STDEV) | |
// alternative -> 0.633s (1% STDEV) | |
// UTF16 -> 0.408s (2% STDEV) | |
// UTF16 nil -> 0.404s (1% STDEV) | |
// "".substring(1,10) | |
// baseline -> 0.074s (4% STDEV) | |
// alternative -> 0.024s (12% STDEV) | |
// UTF16 -> 0.024s (11% STDEV) | |
// UTF16 nil -> 0.019s (12% STDEV) | |
// baseline approach | |
extension String { | |
func substringBaseline(start: Int, end: Int) -> String { | |
if (start == end || self.strlen() == 0) { | |
return "" | |
} | |
let startIndex = self.index(self.startIndex, offsetBy: start) | |
let endIndex = self.index(self.startIndex, offsetBy: end) | |
return self[startIndex..<endIndex] | |
} | |
func strlen() -> Int { | |
return self.characters.count | |
} | |
} | |
// reusing startIndex | |
extension String { | |
func substringAlternative(start: Int, end: Int) -> String { | |
guard !(start == end || isEmpty) else { return "" } | |
let startIndex = index(self.startIndex, offsetBy: start) | |
let endIndex = index(startIndex, offsetBy: end - start) | |
return self[startIndex..<endIndex] | |
} | |
} | |
// using UTF16 | |
extension String { | |
func substringUTF16(start: Int, end: Int) -> String { | |
guard !(start == end || isEmpty) else { return "" } | |
let start16 = String.UTF16Index(start) | |
let end16 = String.UTF16Index(end) | |
return String(utf16[start16..<end16])! | |
} | |
} | |
// using UTF16 with optional return | |
extension String { | |
func substringUTF16Nil(start: Int, end: Int) -> String? { | |
guard !(start == end || isEmpty) else { return nil } | |
let start16 = String.UTF16Index(start) | |
let end16 = String.UTF16Index(end) | |
return String(utf16[start16..<end16]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment