Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,212 @@
</dict>
</dict>
</dict>
<key>StringTests</key>
<dict>
<key>testAnyNumeral()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>1.3081e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testContainsClosure()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>1.5442e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testGrammarLiteralSearch()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>6.0042e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testLine()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>1.7144e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testLiteralSearch()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>6.3992e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testNonExistentLiteralSearch()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>3.4154e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testNotNewLine()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>1.5535e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testOneOrMore()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>9.2286e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testOptionalStringFollowedByNonOptionalString()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>1.0759e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testSkipping1()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>1.1965e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testUppercaseWord()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>2.9068e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testWordBoundary()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>2.5362e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testWordBoundaryManyLanguages()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>3.7748e+06</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
</dict>
<key>UTF8Tests</key>
<dict>
<key>testGrammarLiteralSearch()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>4.1135e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testLine()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>9.6233e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testLiteralSearch()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>8.3321e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testNonExistentLiteralSearch()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>6.0671e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testNotNewLine()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>7.4556e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testOptionalStringFollowedByNonOptionalString()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>8.219e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
<key>testSkipping1()</key>
<dict>
<key>com.apple.dt.XCTMetric_CPU.instructions_retired</key>
<dict>
<key>baselineAverage</key>
<real>2.2521e+05</real>
<key>baselineIntegrationDisplayName</key>
<string>19 Aug 2020 at 20:14:16</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</plist>
1 change: 1 addition & 0 deletions Sources/Patterns/Atomic Patterns/Line.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//

public protocol CharacterLike: Hashable {
@inlinable
var isNewline: Bool { get }
}

Expand Down
4 changes: 3 additions & 1 deletion Sources/Patterns/Operations on Patterns/Skip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,10 @@ public struct Skip<Input: BidirectionalCollection>: Pattern where Input.Element:

import SE0270_RangeSet

extension MutableCollection where Self: RandomAccessCollection, Self: RangeReplaceableCollection, Index == Int {
extension ContiguousArray {
/// Replaces all placeholder `.skip` instructions.
@_specialize(where Input == String, Element == Instruction<String>) // doesn't happen automatically (swiftlang-1200.0.28.1).
@_specialize(where Input == String.UTF8View, Element == Instruction<String.UTF8View>)
@usableFromInline
mutating func replaceSkips<Input>() where Element == Instruction<Input> {
// `setupSkip(at: i)` adds 1 new instruction somewhere after `ì`, so we cant loop over self.indices directly
Expand Down
2 changes: 1 addition & 1 deletion Sources/Patterns/Pattern And Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public enum Instruction<Input: BidirectionalCollection> where Input.Element: Has

extension Sequence {
/// The offset by which these instructions will move the input index.
@inlinable
@usableFromInline
func movesIndexBy<P>() -> Int? where Element == Instruction<P> {
lazy .map { $0.movesIndexBy }.reduceIfNoNils(into: 0) { result, offset in result += offset }
}
Expand Down
7 changes: 7 additions & 0 deletions Sources/Patterns/VMBacktrack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
struct VMEngine<Input: BidirectionalCollection> where Input.Element: Hashable {
@usableFromInline
typealias Instructions = ContiguousArray<Instruction<Input>>
@usableFromInline
let instructions: Instructions

@usableFromInline
Expand All @@ -23,6 +24,8 @@ struct VMEngine<Input: BidirectionalCollection> where Input.Element: Hashable {
self.instructions = instructions
}

@_specialize(where Input == String) // doesn't happen automatically (swiftlang-1200.0.28.1).
@_specialize(where Input == String.UTF8View)
@usableFromInline
func match(in input: Input, at startIndex: Input.Index) -> Parser<Input>.Match? {
launch(input: input, startIndex: startIndex)
Expand Down Expand Up @@ -56,9 +59,13 @@ extension Parser.Match {
extension VMEngine {
@usableFromInline
struct Thread {
@usableFromInline
var instructionIndex: Instructions.Index
@usableFromInline
var inputIndex: Input.Index
@usableFromInline
var captures: ContiguousArray<(index: Input.Index, instruction: Instructions.Index)>
@usableFromInline
var isReturnAddress: Bool = false

@usableFromInline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,7 @@ import XCTest
// Note: the hits parameter to speedTest doesn't necessarily mean the _correct_ number of hits.
// It's just there to notify us when the number of hits changes.

class PerformanceTests: XCTestCase {
func speedTest(_ pattern: Parser<String.UTF8View>, testFile: String = "Long.txt", textFraction: Int = 1, hits: Int,
file: StaticString = #filePath, line: UInt = #line) throws {
let fulltext = try String(contentsOf: getLocalURL(for: testFile))
let text = String(fulltext.prefix(fulltext.count / textFraction)).utf8
var result = 0
let block = {
result = pattern.matches(in: text).reduce(into: 0) { c, _ in c += 1 }
}
#if DEBUG
block()
#else
if #available(OSX 10.15, *) {
let options = XCTMeasureOptions()
options.iterationCount = 10
self.measure(metrics: [XCTCPUMetric(limitingToCurrentThread: true)], options: options, block: block)
} else {
self.measure(block)
}
#endif
XCTAssertEqual(result, hits, file: file, line: line)
}

class StringTests: XCTestCase {
func speedTest(_ pattern: Parser<String>, testFile: String = "Long.txt", textFraction: Int = 1, hits: Int,
file: StaticString = #filePath, line: UInt = #line) throws {
let fulltext = try String(contentsOf: getLocalURL(for: testFile))
Expand Down Expand Up @@ -73,36 +51,36 @@ class PerformanceTests: XCTestCase {
}

func testLine() throws {
let pattern = try Parser<String.UTF8View>(search: Line.Start() • Capture(Skip()) • Line.End())
let pattern = try Parser(search: Line.start • Capture(Skip()) • Line.end)
try speedTest(pattern, textFraction: 2, hits: 7260)
}

func testNotNewLine() throws {
let pattern = try Parser<String.UTF8View>(search: "," • Capture(Skip()) • Line.End())
let pattern = try Parser(search: "," • Capture(Skip()) • Line.End())
try speedTest(pattern, textFraction: 2, hits: 4933)
}

func testLiteralSearch() throws {
let pattern = try Parser<String.UTF8View>(search: Literal("Prince"))
let pattern = try Parser(search: Literal<String>("Prince"))
try speedTest(pattern, textFraction: 1, hits: 2168)
}

func testGrammarLiteralSearch() throws {
func any<Input>() -> OneOf<Input> { OneOf(description: "any", contains: { _ in true }) }

let g = Grammar<String.UTF8View>()
let g = Grammar()
g.a <- Capture("Prince") / any() • g.a
let pattern = try Parser(g)
try speedTest(pattern, textFraction: 13, hits: 260)
}

func testNonExistentLiteralSearch() throws {
let pattern = try Parser<String.UTF8View>(search: "\n" • Skip() • "DOESN'T EXIST")
let pattern = try Parser(search: "\n" • Skip() • "DOESN'T EXIST")
try speedTest(pattern, textFraction: 1, hits: 0)
}

func testOptionalStringFollowedByNonOptionalString() throws {
let pattern = try Parser<String.UTF8View>(search: Literal("\"")¿ • "I")
let pattern = try Parser<String>(search: "\""¿ • "I")
try speedTest(pattern, textFraction: 12, hits: 814)
}

Expand All @@ -113,7 +91,7 @@ class PerformanceTests: XCTestCase {

func testSkipping1() throws {
// [ word.boundary ] * " " * ":" * " " * " " * " " * "{" * Line.end
let pattern = try Parser<String.UTF8View>(search: "." • Skip() • " " • Skip() • " ")
let pattern = try Parser(search: "." • Skip() • " " • Skip() • " ")
try speedTest(pattern, textFraction: 2, hits: 13939)
}

Expand Down
Loading