Last active
October 15, 2018 00:19
-
-
Save milseman/9b579ab001f12676b15b40b1b87e9143 to your computer and use it in GitHub Desktop.
Extracted from Substring.swift benchmark
This file contains 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
print("start") | |
public var i = 0 | |
// @inline(never) | |
// public func blackHole<T>(_ x: T) { | |
// i += 1 | |
// } | |
@inline(never) | |
public func blackHole(_ x: Bool) { | |
i += x ? 1 : 0 | |
} | |
@inline(never) | |
public func blackHole<C: Collection>(_ x: C) { | |
i += x.isEmpty ? 1 : 0 | |
} | |
@inline(never) | |
public func blackHole<T>(_ x: UnsafeMutablePointer<T>) { | |
i += UInt(bitPattern: x) % 2 == 0 ? 1 : 0 | |
} | |
@inline(never) | |
public func CheckResults(_ x: Bool) { | |
guard x else { fatalError() } | |
} | |
// import TestsUtils | |
// public let SubstringTest = [ | |
// BenchmarkInfo(name: "EqualStringSubstring", runFunction: run_EqualStringSubstring, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "EqualSubstringString", runFunction: run_EqualSubstringString, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "EqualSubstringSubstring", runFunction: run_EqualSubstringSubstring, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "EqualSubstringSubstringGenericEquatable", runFunction: run_EqualSubstringSubstringGenericEquatable, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "LessSubstringSubstring", runFunction: run_LessSubstringSubstring, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "LessSubstringSubstringGenericComparable", runFunction: run_LessSubstringSubstringGenericComparable, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "StringFromLongWholeSubstring", runFunction: run_StringFromLongWholeSubstring, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "StringFromLongWholeSubstringGeneric", runFunction: run_StringFromLongWholeSubstringGeneric, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "SubstringComparable", runFunction: run_SubstringComparable, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "SubstringEqualString", runFunction: run_SubstringEqualString, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "SubstringEquatable", runFunction: run_SubstringEquatable, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "SubstringFromLongString", runFunction: run_SubstringFromLongString, tags: [.validation, .api, .String]), | |
// BenchmarkInfo(name: "SubstringFromLongStringGeneric", runFunction: run_SubstringFromLongStringGeneric, tags: [.validation, .api, .String]), | |
// ] | |
// A string that doesn't fit in small string storage and doesn't fit in Latin-1 | |
let longWide = "fα½’asα½’odα½’ijα½’adα½’olα½’sjα½’alα½’sdα½’jlα½’asα½’dfα½’ijα½’liα½’sdα½’jΓΈα½’slα½’diα½’alα½’iα½’" | |
@inline(never) | |
public func run_SubstringFromLongString(_ N: Int) { | |
var s = longWide | |
s += "!" // ensure the string has a real buffer | |
for _ in 1...N*500 { | |
blackHole(Substring(s)) | |
} | |
} | |
func create<T : RangeReplaceableCollection, U : Collection>( | |
_: T.Type, from source: U | |
) where T.Element == U.Element { | |
blackHole(T(source)) | |
} | |
@inline(never) | |
public func run_SubstringFromLongStringGeneric(_ N: Int) { | |
var s = longWide | |
s += "!" // ensure the string has a real buffer | |
for _ in 1...N*500 { | |
create(Substring.self, from: s) | |
} | |
} | |
@inline(never) | |
public func run_StringFromLongWholeSubstring(_ N: Int) { | |
var s0 = longWide | |
s0 += "!" // ensure the string has a real buffer | |
let s = Substring(s0) | |
for _ in 1...N*500 { | |
blackHole(String(s)) | |
} | |
} | |
@inline(never) | |
public func run_StringFromLongWholeSubstringGeneric(_ N: Int) { | |
var s0 = longWide | |
s0 += "!" // ensure the string has a real buffer | |
let s = Substring(s0) | |
for _ in 1...N*500 { | |
create(String.self, from: s) | |
} | |
} | |
private func equivalentWithDistinctBuffers() -> (String, Substring) { | |
var s0 = longWide | |
withUnsafeMutablePointer(to: &s0) { blackHole($0) } | |
s0 += "!" | |
// These two should be equal but with distinct buffers, both refcounted. | |
let a = Substring(s0).dropFirst() | |
let b = String(a) | |
return (b, a) | |
} | |
@inline(never) | |
public func run_EqualStringSubstring(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
blackHole(a == b) | |
} | |
} | |
@inline(never) | |
public func run_EqualSubstringString(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
blackHole(b == a) | |
} | |
} | |
@inline(never) | |
public func run_EqualSubstringSubstring(_ N: Int) { | |
let (_, a) = equivalentWithDistinctBuffers() | |
let (_, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
blackHole(a == b) | |
} | |
} | |
@inline(never) | |
public func run_EqualSubstringSubstringGenericEquatable(_ N: Int) { | |
let (_, a) = equivalentWithDistinctBuffers() | |
let (_, b) = equivalentWithDistinctBuffers() | |
func check<T>(_ x: T, _ y: T) where T : Equatable { | |
blackHole(x == y) | |
} | |
for _ in 1...N*500 { | |
check(a, b) | |
} | |
} | |
/* | |
func checkEqual<T, U>(_ x: T, _ y: U) | |
where T : StringProtocol, U : StringProtocol { | |
blackHole(x == y) | |
} | |
@inline(never) | |
public func run _EqualStringSubstringGenericStringProtocol(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
checkEqual(a, b) | |
} | |
} | |
@inline(never) | |
public func run _EqualSubstringStringGenericStringProtocol(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
checkEqual(b, a) | |
} | |
} | |
@inline(never) | |
public func run _EqualSubstringSubstringGenericStringProtocol(_ N: Int) { | |
let (_, a) = equivalentWithDistinctBuffers() | |
let (_, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
checkEqual(a, b) | |
} | |
} | |
*/ | |
//===----------------------------------------------------------------------===// | |
/* | |
@inline(never) | |
public func run _LessStringSubstring(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
blackHole(a < b) | |
} | |
} | |
@inline(never) | |
public func run _LessSubstringString(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
blackHole(b < a) | |
} | |
} | |
*/ | |
@inline(never) | |
public func run_LessSubstringSubstring(_ N: Int) { | |
let (_, a) = equivalentWithDistinctBuffers() | |
let (_, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
blackHole(a < b) | |
} | |
} | |
@inline(never) | |
public func run_LessSubstringSubstringGenericComparable(_ N: Int) { | |
let (_, a) = equivalentWithDistinctBuffers() | |
let (_, b) = equivalentWithDistinctBuffers() | |
func check<T>(_ x: T, _ y: T) where T : Comparable { | |
blackHole(x < y) | |
} | |
for _ in 1...N*500 { | |
check(a, b) | |
} | |
} | |
@inline(never) | |
public func run_SubstringEquatable(_ N: Int) { | |
var string = "pen,pineapple,apple,pen" | |
string += ",βοΈ,π,π,βοΈ" | |
let substrings = string.split(separator: ",") | |
var count = 0 | |
for _ in 1...N*500 { | |
for s in substrings { | |
if substrings.contains(s) { count = count &+ 1 } | |
} | |
} | |
CheckResults(count == 8*N*500) | |
} | |
@inline(never) | |
public func run_SubstringEqualString(_ N: Int) { | |
var string = "pen,pineapple,apple,pen" | |
string += ",βοΈ,π,π,βοΈ" | |
let substrings = string.split(separator: ",") | |
let pineapple = "pineapple" | |
let apple = "π" | |
var count = 0 | |
for _ in 1...N*500 { | |
for s in substrings { | |
if s == pineapple || s == apple { count = count &+ 1 } | |
} | |
} | |
CheckResults(count == 2*N*500) | |
} | |
@inline(never) | |
public func run_SubstringComparable(_ N: Int) { | |
var string = "pen,pineapple,apple,pen" | |
string += ",βοΈ,π,π,βοΈ" | |
let substrings = string.split(separator: ",") | |
let comparison = substrings + ["PPAP"] | |
var count = 0 | |
for _ in 1...N*500 { | |
if substrings.lexicographicallyPrecedes(comparison) { | |
count = count &+ 1 | |
} | |
} | |
CheckResults(count == N*500) | |
} | |
/* | |
func checkLess<T, U>(_ x: T, _ y: U) | |
where T : StringProtocol, U : StringProtocol { | |
blackHole(x < y) | |
} | |
@inline(never) | |
public func run _LessStringSubstringGenericStringProtocol(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
checkLess(a, b) | |
} | |
} | |
@inline(never) | |
public func run _LessSubstringStringGenericStringProtocol(_ N: Int) { | |
let (a, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
checkLess(b, a) | |
} | |
} | |
@inline(never) | |
public func run _LessSubstringSubstringGenericStringProtocol(_ N: Int) { | |
let (_, a) = equivalentWithDistinctBuffers() | |
let (_, b) = equivalentWithDistinctBuffers() | |
for _ in 1...N*500 { | |
checkLess(a, b) | |
} | |
} | |
*/ | |
import Dispatch | |
func time<T>(_ _caller : String = #function, _ block: () -> T) -> T { | |
let start = DispatchTime.now() | |
let res = block() | |
let end = DispatchTime.now() | |
let milliseconds = (end.uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000 | |
print("\(_caller)\t\(milliseconds)") | |
// print("result: \(res)") | |
return res | |
} | |
let N = 1_000 | |
print("Running...") | |
time("EqualStringSubstring") { | |
run_EqualStringSubstring(N * 32) | |
} | |
time("EqualSubstringString") { | |
run_EqualSubstringString(N * 20) | |
} | |
time("EqualSubstringSubstring") { | |
run_EqualSubstringSubstring(N * 20) | |
} | |
time("EqualSubstringSubstringGenericEquatable") { | |
run_EqualSubstringSubstringGenericEquatable(N * 20) | |
} | |
time("LessSubstringSubstring") { | |
run_LessSubstringSubstring(N * 20) | |
} | |
time("LessSubstringSubstringGenericComparable") { | |
run_LessSubstringSubstringGenericComparable(N * 20) | |
} | |
time("SubstringComparable") { | |
run_SubstringComparable(N * 8) | |
} | |
time("SubstringEqualString") { | |
run_SubstringEqualString(N / 4) | |
} | |
time("SubstringEquatable") { | |
run_SubstringEquatable(N / 8) | |
} | |
time("StringFromLongWholeSubstringGeneric") { | |
run_StringFromLongWholeSubstringGeneric(N * 4) | |
} | |
time("StringFromLongWholeSubstring ") { | |
run_StringFromLongWholeSubstring(N * 4) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment