Skip to content

Commit 8017a63

Browse files
authored
Merge pull request swiftlang#75 from benlangmuir/perfkill
[test] Disable performance metrics unless ENABLE_PERF_TESTS is defined
2 parents e8909fd + e47c7db commit 8017a63

File tree

6 files changed

+156
-76
lines changed

6 files changed

+156
-76
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,6 @@ let package = Package(
8282
dependencies: ["SwiftPM"]),
8383
.testTarget(
8484
name: "SKSupportTests",
85-
dependencies: ["SKSupport"]),
85+
dependencies: ["SKSupport", "SKTestSupport"]),
8686
]
8787
)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import XCTest
14+
15+
/// Base class for a performance test case in SourceKit-LSP.
16+
///
17+
/// This allows writing performance tests whose performance tracking is only
18+
/// enabled when ENABLE_PERF_TESTS is defined. Otherwise, the test is still
19+
/// executed, but no metrics are enabled, and the measured block is only run
20+
/// once, which is useful to avoid failures due to high variability in
21+
/// continuous integration.
22+
open class PerfTestCase: XCTestCase {
23+
24+
#if !ENABLE_PERF_TESTS
25+
26+
#if os(macOS)
27+
open override func startMeasuring() {}
28+
open override func stopMeasuring() {}
29+
open override func measureMetrics(
30+
_: [XCTPerformanceMetric],
31+
automaticallyStartMeasuring: Bool,
32+
for block: () -> Void)
33+
{
34+
block()
35+
}
36+
#else
37+
// In corelibs-xctest, these methods are public, not open, so we can only
38+
// shadow them.
39+
public func startMeasuring() {}
40+
public func stopMeasuring() {}
41+
public func measureMetrics(
42+
_: [XCTPerformanceMetric],
43+
automaticallyStartMeasuring: Bool,
44+
for block: () -> Void)
45+
{
46+
block()
47+
}
48+
#endif
49+
#endif
50+
51+
}

Tests/LanguageServerProtocolJSONRPCTests/ConnectionPerfTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import LanguageServerProtocolJSONRPC
1515
import SKTestSupport
1616
import XCTest
1717

18-
class ConnectionPerfTests: XCTestCase {
18+
class ConnectionPerfTests: PerfTestCase {
1919

2020
var connection: TestJSONRPCConnection! = nil
2121

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
@testable import SKSupport
14+
import SKTestSupport
15+
import Basic
16+
import POSIX
17+
import XCTest
18+
19+
final class SupportPerfTests: PerfTestCase {
20+
21+
func testLineTableAppendPerf() {
22+
23+
let characters: [Character] = [
24+
"\t", "\n"
25+
] + (32...126).map { Character(UnicodeScalar($0)) }
26+
27+
// The debug performance is shockingly bad.
28+
#if DEBUG
29+
let iterations = 1_000
30+
#else
31+
let iterations = 10_000
32+
#endif
33+
34+
self.measure {
35+
var lcg = SimpleLCG(seed: 1)
36+
var t = LineTable("")
37+
var line = 0
38+
var col = 0
39+
for _ in 1...iterations {
40+
let c = characters.randomElement(using: &lcg)!
41+
t.replace(fromLine: line, utf16Offset: col, toLine: line, utf16Offset: col, with: String(c))
42+
col += 1
43+
if c == "\n" {
44+
line += 1
45+
col = 0
46+
}
47+
}
48+
}
49+
}
50+
51+
func testLineTableSingleCharEditPerf() {
52+
53+
let characters: [Character] = [
54+
"\t", "\n"
55+
] + (32...126).map { Character(UnicodeScalar($0)) }
56+
57+
// The debug performance is shockingly bad.
58+
#if DEBUG
59+
let iterations = 1_000
60+
let size = 1_000
61+
#else
62+
let iterations = 10_000
63+
let size = 10_000
64+
#endif
65+
66+
self.measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
67+
var lcg = SimpleLCG(seed: 1)
68+
var str = ""
69+
for _ in 1...size {
70+
str += String(characters.randomElement(using: &lcg)!)
71+
}
72+
73+
var t = LineTable(str)
74+
75+
self.startMeasuring()
76+
77+
for _ in 1...iterations {
78+
let line = (0..<(t.count-1)).randomElement(using: &lcg)!
79+
let col = (0 ..< t[line].utf16.count).randomElement(using: &lcg)!
80+
let len = Bool.random() ? 1 : 0
81+
var newText = String(characters.randomElement(using: &lcg)!)
82+
if len == 1 && Bool.random(using: &lcg) {
83+
newText = "" // deletion
84+
}
85+
86+
t.replace(fromLine: line, utf16Offset: col, utf16Length: len, with: newText)
87+
}
88+
89+
self.stopMeasuring()
90+
}
91+
}
92+
}

Tests/SKSupportTests/SupportTests.swift

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -439,78 +439,6 @@ final class SupportTests: XCTestCase {
439439
XCTAssertEqual(t, LineTable("abp\nq\ngh"))
440440
}
441441

442-
func testLineTableAppendPerf() {
443-
444-
let characters: [Character] = [
445-
"\t", "\n"
446-
] + (32...126).map { Character(UnicodeScalar($0)) }
447-
448-
// The debug performance is shockingly bad.
449-
#if DEBUG
450-
let iterations = 1_000
451-
#else
452-
let iterations = 10_000
453-
#endif
454-
455-
self.measure {
456-
var lcg = SimpleLCG(seed: 1)
457-
var t = LineTable("")
458-
var line = 0
459-
var col = 0
460-
for _ in 1...iterations {
461-
let c = characters.randomElement(using: &lcg)!
462-
t.replace(fromLine: line, utf16Offset: col, toLine: line, utf16Offset: col, with: String(c))
463-
col += 1
464-
if c == "\n" {
465-
line += 1
466-
col = 0
467-
}
468-
}
469-
}
470-
}
471-
472-
func testLineTableSingleCharEditPerf() {
473-
474-
let characters: [Character] = [
475-
"\t", "\n"
476-
] + (32...126).map { Character(UnicodeScalar($0)) }
477-
478-
// The debug performance is shockingly bad.
479-
#if DEBUG
480-
let iterations = 1_000
481-
let size = 1_000
482-
#else
483-
let iterations = 10_000
484-
let size = 10_000
485-
#endif
486-
487-
self.measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
488-
var lcg = SimpleLCG(seed: 1)
489-
var str = ""
490-
for _ in 1...size {
491-
str += String(characters.randomElement(using: &lcg)!)
492-
}
493-
494-
var t = LineTable(str)
495-
496-
self.startMeasuring()
497-
498-
for _ in 1...iterations {
499-
let line = (0..<(t.count-1)).randomElement(using: &lcg)!
500-
let col = (0 ..< t[line].utf16.count).randomElement(using: &lcg)!
501-
let len = Bool.random() ? 1 : 0
502-
var newText = String(characters.randomElement(using: &lcg)!)
503-
if len == 1 && Bool.random(using: &lcg) {
504-
newText = "" // deletion
505-
}
506-
507-
t.replace(fromLine: line, utf16Offset: col, utf16Length: len, with: newText)
508-
}
509-
510-
self.stopMeasuring()
511-
}
512-
}
513-
514442
func testByteStringWithUnsafeData() {
515443
ByteString(encodingAsUTF8: "").withUnsafeData { data in
516444
XCTAssertEqual(data.count, 0)

Tests/SKSupportTests/XCTestManifests.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
#if !canImport(ObjectiveC)
22
import XCTest
33

4+
extension SupportPerfTests {
5+
// DO NOT MODIFY: This is autogenerated, use:
6+
// `swift test --generate-linuxmain`
7+
// to regenerate.
8+
static let __allTests__SupportPerfTests = [
9+
("testLineTableAppendPerf", testLineTableAppendPerf),
10+
("testLineTableSingleCharEditPerf", testLineTableSingleCharEditPerf),
11+
]
12+
}
13+
414
extension SupportTests {
515
// DO NOT MODIFY: This is autogenerated, use:
616
// `swift test --generate-linuxmain`
@@ -11,10 +21,8 @@ extension SupportTests {
1121
("testFindSubsequence", testFindSubsequence),
1222
("testIntFromAscii", testIntFromAscii),
1323
("testLineTable", testLineTable),
14-
("testLineTableAppendPerf", testLineTableAppendPerf),
1524
("testLineTableEditing", testLineTableEditing),
1625
("testLineTableLinePositionTranslation", testLineTableLinePositionTranslation),
17-
("testLineTableSingleCharEditPerf", testLineTableSingleCharEditPerf),
1826
("testLogging", testLogging),
1927
("testResultEquality", testResultEquality),
2028
("testResultProjection", testResultProjection),
@@ -23,6 +31,7 @@ extension SupportTests {
2331

2432
public func __allTests() -> [XCTestCaseEntry] {
2533
return [
34+
testCase(SupportPerfTests.__allTests__SupportPerfTests),
2635
testCase(SupportTests.__allTests__SupportTests),
2736
]
2837
}

0 commit comments

Comments
 (0)