mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Spelling benchmark (#42457)
* spelling: approximate Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: benchmarks Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: calculation Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: characterization Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: coefficient Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: computation Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: deterministic Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: divisor Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: encounter Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: expected Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: fibonacci Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: fulfill Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: implements Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: into Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: intrinsic Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: markdown Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: measure Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurrences Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: omitted Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: partition Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: performance Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: practice Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: preemptive Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: repeated Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: requirements Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: requires Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: supports Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unknown Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: utilities Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: verbose Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
This commit is contained in:
@@ -241,7 +241,7 @@ set(SWIFT_BENCHMARK_EXTRA_FLAGS "" CACHE STRING
|
||||
"Extra options to pass to swiftc when building the benchmarks")
|
||||
|
||||
set(SWIFT_BENCHMARK_UNOPTIMIZED_DRIVER NO CACHE BOOL
|
||||
"Build the benchmark driver utilites without optimization (default: no)")
|
||||
"Build the benchmark driver utilities without optimization (default: no)")
|
||||
|
||||
if (SWIFT_BENCHMARK_BUILT_STANDALONE)
|
||||
# This option's value must match the value of the same option used when
|
||||
|
||||
@@ -20,7 +20,7 @@ Example:
|
||||
|
||||
Use `Benchmark_Driver -h` for help on available commands and options.
|
||||
|
||||
class `BenchmarkDriver` runs performance tests and impements the `run` COMMAND.
|
||||
class `BenchmarkDriver` runs performance tests and implements the `run` COMMAND.
|
||||
class `BenchmarkDoctor` analyzes performance tests, implements `check` COMMAND.
|
||||
|
||||
"""
|
||||
@@ -544,7 +544,7 @@ class BenchmarkDoctor(object):
|
||||
caveat = "" if setup == 0 else " (excluding the setup overhead)"
|
||||
log("'%s' execution took at least %d μs%s.", name, runtime, caveat)
|
||||
|
||||
def factor(base): # suitable divisior that's integer power of base
|
||||
def factor(base): # suitable divisor that's integer power of base
|
||||
return int(
|
||||
pow(base, math.ceil(math.log(runtime / float(threshold), base)))
|
||||
)
|
||||
@@ -718,7 +718,7 @@ class BenchmarkDoctor(object):
|
||||
return measurements
|
||||
|
||||
def analyze(self, benchmark_measurements):
|
||||
"""Analyze whether benchmark fullfills all requirtements."""
|
||||
"""Analyze whether benchmark fulfills all requirements."""
|
||||
self.log.debug("Analyzing %s", benchmark_measurements["name"])
|
||||
for rule in self.requirements:
|
||||
rule(benchmark_measurements)
|
||||
|
||||
@@ -22,7 +22,7 @@ class `PerformanceTestSamples` is collection of `Sample`s and their statistics.
|
||||
class `PerformanceTestResult` is a summary of performance test execution.
|
||||
class `LogParser` converts log files into `PerformanceTestResult`s.
|
||||
class `ResultComparison` compares new and old `PerformanceTestResult`s.
|
||||
class `TestComparator` analyzes changes betweeen the old and new test results.
|
||||
class `TestComparator` analyzes changes between the old and new test results.
|
||||
class `ReportFormatter` creates the test comparison report in specified format.
|
||||
|
||||
"""
|
||||
@@ -111,7 +111,7 @@ class PerformanceTestSamples(object):
|
||||
|
||||
Experimentally, this rule seems to perform well-enough on the
|
||||
benchmark runtimes in the microbenchmark range to filter out
|
||||
the environment noise caused by preemtive multitasking.
|
||||
the environment noise caused by preemptive multitasking.
|
||||
"""
|
||||
lo = (
|
||||
0
|
||||
@@ -205,7 +205,7 @@ class PerformanceTestSamples(object):
|
||||
|
||||
@property
|
||||
def cv(self):
|
||||
"""Coeficient of Variation (%)."""
|
||||
"""Coefficient of Variation (%)."""
|
||||
return (self.sd / self.mean) if self.mean else 0
|
||||
|
||||
@property
|
||||
@@ -225,7 +225,7 @@ class PerformanceTestResult(object):
|
||||
Reported by the test driver (Benchmark_O, Benchmark_Onone, Benchmark_Osize
|
||||
or Benchmark_Driver).
|
||||
|
||||
It suppors 2 log formats emitted by the test driver. Legacy format with
|
||||
It supports 2 log formats emitted by the test driver. Legacy format with
|
||||
statistics for normal distribution (MEAN, SD):
|
||||
#,TEST,SAMPLES,MIN(μs),MAX(μs),MEAN(μs),SD(μs),MEDIAN(μs),MAX_RSS(B)
|
||||
And new quantiles format with variable number of columns:
|
||||
@@ -311,7 +311,7 @@ class PerformanceTestResult(object):
|
||||
"""Merge two results.
|
||||
|
||||
Recomputes min, max and mean statistics. If all `samples` are
|
||||
avaliable, it recomputes all the statistics.
|
||||
available, it recomputes all the statistics.
|
||||
The use case here is comparing test results parsed from concatenated
|
||||
log files from multiple runs of benchmark driver.
|
||||
"""
|
||||
@@ -514,12 +514,12 @@ class LogParser(object):
|
||||
|
||||
|
||||
class TestComparator(object):
|
||||
"""Analyzes changes betweeen the old and new test results.
|
||||
"""Analyzes changes between the old and new test results.
|
||||
|
||||
It determines which tests were `added`, `removed` and which can be
|
||||
compared. It then splits the `ResultComparison`s into 3 groups according to
|
||||
the `delta_threshold` by the change in performance: `increased`,
|
||||
`descreased` and `unchanged`. Whole computaion is performed during
|
||||
`descreased` and `unchanged`. Whole computation is performed during
|
||||
initialization and results are provided as properties on this object.
|
||||
|
||||
The lists of `added`, `removed` and `unchanged` tests are sorted
|
||||
@@ -576,7 +576,7 @@ class TestComparator(object):
|
||||
|
||||
|
||||
class ReportFormatter(object):
|
||||
"""Creates the report from perfromance test comparison in specified format.
|
||||
"""Creates the report from performance test comparison in specified format.
|
||||
|
||||
`ReportFormatter` formats the `PerformanceTestResult`s and
|
||||
`ResultComparison`s provided by `TestComparator` into report table.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#
|
||||
# Performs a very fast check which benchmarks regressed and improved.
|
||||
#
|
||||
# Initially runs the benchmars with a low sample count and just re-runs those
|
||||
# Initially runs the benchmarks with a low sample count and just re-runs those
|
||||
# benchmarks which differ.
|
||||
# Also reports code size differences.
|
||||
#
|
||||
@@ -224,7 +224,7 @@ def measure(driver, tests, i):
|
||||
|
||||
|
||||
def merge(results, other_results):
|
||||
""""Merge the other PreformanceTestResults into the first dictionary."""
|
||||
""""Merge the other PerformanceTestResults into the first dictionary."""
|
||||
for test, result in other_results.items():
|
||||
results[test].merge(result)
|
||||
return results
|
||||
|
||||
@@ -135,12 +135,12 @@ class Test_parse_args(unittest.TestCase):
|
||||
self.assertIsNone(parse_args(["run"]).output_dir)
|
||||
self.assertEqual(parse_args(["run", "--output-dir", "/log"]).output_dir, "/log")
|
||||
|
||||
def test_check_supports_vebose_output(self):
|
||||
def test_check_supports_verbose_output(self):
|
||||
self.assertFalse(parse_args(["check"]).verbose)
|
||||
self.assertTrue(parse_args(["check", "-v"]).verbose)
|
||||
self.assertTrue(parse_args(["check", "--verbose"]).verbose)
|
||||
|
||||
def test_check_supports_mardown_output(self):
|
||||
def test_check_supports_markdown_output(self):
|
||||
self.assertFalse(parse_args(["check"]).markdown)
|
||||
self.assertTrue(parse_args(["check", "-md"]).markdown)
|
||||
self.assertTrue(parse_args(["check", "--markdown"]).markdown)
|
||||
@@ -486,7 +486,7 @@ class TestBenchmarkDriverRunningTests(unittest.TestCase):
|
||||
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
def test_deterministing_hashing(self):
|
||||
def test_deterministic_hashing(self):
|
||||
cmd = ["printenv", "SWIFT_DETERMINISTIC_HASHING"]
|
||||
driver = BenchmarkDriver(["no args"], tests=["ignored"])
|
||||
self.assertEqual(driver._invoke(cmd).strip(), "1")
|
||||
@@ -839,7 +839,7 @@ class TestBenchmarkDoctor(unittest.TestCase):
|
||||
quantum used by macos scheduler. Linux scheduler's quantum is 6ms.
|
||||
Driver yielding the process before the 10ms quantum elapses helped
|
||||
a lot, but benchmarks with runtimes under 1ms usually exhibit a strong
|
||||
mode which is best for accurate performance charaterization.
|
||||
mode which is best for accurate performance characterization.
|
||||
To minimize the number of involuntary context switches that corrupt our
|
||||
measurements, we should strive to stay in the microbenchmark range.
|
||||
|
||||
@@ -999,7 +999,7 @@ class TestBenchmarkDoctor(unittest.TestCase):
|
||||
doctor.analyze(
|
||||
{
|
||||
# The threshold of 15 pages was estimated from previous
|
||||
# measurements. The normal range should be probably aproximated
|
||||
# measurements. The normal range should be probably approximate
|
||||
# by a function instead of a simple constant.
|
||||
# TODO: re-evaluate normal range from whole SBS
|
||||
"name": "ConstantMemory",
|
||||
|
||||
@@ -247,7 +247,7 @@ class TestPerformanceTestResult(unittest.TestCase):
|
||||
def test_init_delta_quantiles(self):
|
||||
# #,TEST,SAMPLES,MIN(μs),𝚫MEDIAN,𝚫MAX
|
||||
# 2-quantile from 2 samples in repeated min, when delta encoded,
|
||||
# the difference is 0, which is ommited -- only separator remains
|
||||
# the difference is 0, which is omitted -- only separator remains
|
||||
log = "202,DropWhileArray,2,265,,22"
|
||||
r = PerformanceTestResult(log.split(","), quantiles=True, delta=True)
|
||||
self.assertEqual((r.num_samples, r.min, r.median, r.max), (2, 265, 265, 287))
|
||||
@@ -257,7 +257,7 @@ class TestPerformanceTestResult(unittest.TestCase):
|
||||
def test_init_oversampled_quantiles(self):
|
||||
"""When num_samples is < quantile + 1, some of the measurements are
|
||||
repeated in the report summary. Samples should contain only true
|
||||
values, discarding the repetated artifacts from quantile estimation.
|
||||
values, discarding the repeated artifacts from quantile estimation.
|
||||
|
||||
The test string is slightly massaged output of the following R script:
|
||||
subsample <- function(x, q) {
|
||||
@@ -517,7 +517,7 @@ class OldAndNewLog(unittest.TestCase):
|
||||
|
||||
class TestLogParser(unittest.TestCase):
|
||||
def test_parse_results_csv(self):
|
||||
"""Ignores uknown lines, extracts data from supported formats."""
|
||||
"""Ignores unknown lines, extracts data from supported formats."""
|
||||
log = """#,TEST,SAMPLES,MIN(us),MAX(us),MEAN(us),SD(us),MEDIAN(us)
|
||||
7,Array.append.Array.Int?,20,10,10,10,0,10
|
||||
21,Bridging.NSArray.as!.Array.NSString,20,11,11,11,0,11
|
||||
|
||||
@@ -69,7 +69,7 @@ class Mock(object):
|
||||
def expect(self, call_args, response):
|
||||
"""Expect invocation of tested method with given arguments.
|
||||
|
||||
Stores the canned reponse in the `respond` dictionary.
|
||||
Stores the canned response in the `respond` dictionary.
|
||||
"""
|
||||
call_args = tuple(call_args)
|
||||
self.expected.append(call_args)
|
||||
@@ -83,7 +83,7 @@ class Mock(object):
|
||||
)
|
||||
|
||||
def assert_called_all_expected(self):
|
||||
"""Verify that all expeced invocations of tested method were called."""
|
||||
"""Verify that all expected invocations of tested method were called."""
|
||||
assert self.calls == self.expected, "\nExpected: {0}, \n Called: {1}".format(
|
||||
self.expected, self.calls
|
||||
)
|
||||
|
||||
@@ -323,7 +323,7 @@ class UTF16ToIdxRange: BenchmarkBase {
|
||||
}
|
||||
|
||||
/// Split a string into `count` random slices and convert their index ranges
|
||||
/// into into UTF-16 offset pairs.
|
||||
/// into UTF-16 offset pairs.
|
||||
class IdxToUTF16Range: BenchmarkBase {
|
||||
let count: Int
|
||||
var inputIndices: [Range<String.Index>] = []
|
||||
|
||||
@@ -72,7 +72,7 @@ extension MapSomeSequenceView: Sequence {
|
||||
}
|
||||
|
||||
// now extend a lazy collection to return that view
|
||||
// from a call to mapSome. In pracice, when doing this,
|
||||
// from a call to mapSome. In practice, when doing this,
|
||||
// you should do it for all the lazy wrappers
|
||||
// (i.e. random-access, forward and sequence)
|
||||
extension LazyCollectionProtocol {
|
||||
|
||||
@@ -72,7 +72,7 @@ extension MapSomeSequenceView: Sequence {
|
||||
}
|
||||
|
||||
// now extend a lazy collection to return that view
|
||||
// from a call to mapSome. In pracice, when doing this,
|
||||
// from a call to mapSome. In practice, when doing this,
|
||||
// you should do it for all the lazy wrappers
|
||||
// (i.e. random-access, forward and sequence)
|
||||
extension LazyCollectionProtocol {
|
||||
@@ -219,7 +219,7 @@ let combineDoubleDigits = {
|
||||
(10...18).contains($0) ? $0-9 : $0
|
||||
}
|
||||
|
||||
// first, the lazy version of checksum calcuation
|
||||
// first, the lazy version of checksum calculation
|
||||
let lazychecksum = { (ccnum: String) -> Bool in
|
||||
ccnum.lazy
|
||||
|> reverse
|
||||
|
||||
@@ -120,7 +120,7 @@ public func run_SIMDReduceInt32x4_init(_ n: Int) {
|
||||
@inline(never)
|
||||
public func run_SIMDReduceInt32x4_cast(_ n: Int) {
|
||||
// Morally it seems like we "should" be able to use withMemoryRebound
|
||||
// to SIMD4<Int32>, but that function requries that the sizes match in
|
||||
// to SIMD4<Int32>, but that function requires that the sizes match in
|
||||
// debug builds, so this is pretty ugly. The following "works" for now,
|
||||
// but is probably in violation of the formal model (the exact rules
|
||||
// for "assumingMemoryBound" are not clearly documented). We need a
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
// This benchmark is derived from user code that encoutered a major
|
||||
// This benchmark is derived from user code that encountered a major
|
||||
// performance problem in normal usage. Contributed by Saleem
|
||||
// Abdulrasool (compnerd).
|
||||
//
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import TestsUtils
|
||||
|
||||
// This benchmark aims to measuare heapSort path of stdlib sorting function.
|
||||
// This benchmark aims to measure heapSort path of stdlib sorting function.
|
||||
// Datasets in this benchmark are influenced by stdlib partition function,
|
||||
// therefore if stdlib partion implementation changes we should correct these
|
||||
// therefore if stdlib partition implementation changes we should correct these
|
||||
// datasets or disable/skip this benchmark
|
||||
public let benchmarks = [
|
||||
BenchmarkInfo(
|
||||
|
||||
@@ -245,7 +245,7 @@ public func run_WordCountUniqueUTF16(_ n: Int) {
|
||||
}
|
||||
|
||||
/// Returns an array of all words in the supplied string, along with their
|
||||
/// number of occurances. The array is sorted by decreasing frequency.
|
||||
/// number of occurrences. The array is sorted by decreasing frequency.
|
||||
/// (Words are case-sensitive and only support a limited subset of Unicode.)
|
||||
@inline(never)
|
||||
func histogram<S: Sequence>(for words: S) -> [(String, Int)]
|
||||
|
||||
@@ -31,7 +31,7 @@ public enum BenchmarkCategory : String {
|
||||
case exclusivity, differentiation
|
||||
|
||||
// Algorithms are "micro" that test some well-known algorithm in isolation:
|
||||
// sorting, searching, hashing, fibonaci, crypto, etc.
|
||||
// sorting, searching, hashing, fibonacci, crypto, etc.
|
||||
case algorithm
|
||||
|
||||
// Miniapplications are contrived to mimic some subset of application behavior
|
||||
@@ -55,7 +55,7 @@ public enum BenchmarkCategory : String {
|
||||
// counterproductive.
|
||||
case unstable
|
||||
|
||||
// CPU benchmarks represent instrinsic Swift performance. They are useful for
|
||||
// CPU benchmarks represent intrinsic Swift performance. They are useful for
|
||||
// measuring a fully baked Swift implementation across different platforms and
|
||||
// hardware. The benchmark should also be reasonably applicable to real Swift
|
||||
// code--it should exercise a known performance critical area. Typically these
|
||||
|
||||
Reference in New Issue
Block a user