From b3fe93cc18d18b7e0c253393ac657d696f385832 Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Wed, 2 Aug 2017 18:55:39 +0700 Subject: [PATCH] Enable performance testsuite --- .gitignore | 2 + build.gradle | 6 + performance/build.gradle | 21 + performance/gradle.properties | 1 + performance/src/main/kotlin/main.kt | 14 + .../jetbrains/ring/AbstractMethodBenchmark.kt | 36 + .../org/jetbrains/ring/ClassArrayBenchmark.kt | 90 +++ .../jetbrains/ring/ClassBaselineBenchmark.kt | 61 ++ .../org/jetbrains/ring/ClassListBenchmark.kt | 120 ++++ .../jetbrains/ring/ClassStreamBenchmark.kt | 85 +++ .../ring/CompanionObjectBenchmark.kt | 23 + .../main/kotlin/org/jetbrains/ring/Data.kt | 84 +++ .../ring/DefaultArgumentBenchmark.kt | 65 ++ .../org/jetbrains/ring/ElvisBenchmark.kt | 21 + .../org/jetbrains/ring/EulerBenchmark.kt | 199 ++++++ .../org/jetbrains/ring/FibonacciBenchmark.kt | 70 ++ .../org/jetbrains/ring/InlineBenchmark.kt | 57 ++ .../org/jetbrains/ring/IntArrayBenchmark.kt | 155 +++++ .../jetbrains/ring/IntBaselineBenchmark.kt | 43 ++ .../org/jetbrains/ring/IntListBenchmark.kt | 90 +++ .../org/jetbrains/ring/IntStreamBenchmark.kt | 85 +++ .../org/jetbrains/ring/LambdaBenchmark.kt | 90 +++ .../org/jetbrains/ring/LoopBenchmark.kt | 62 ++ .../org/jetbrains/ring/MatrixMapBenchmark.kt | 57 ++ .../ParameterNotNullAssertionBenchmark.kt | 61 ++ .../org/jetbrains/ring/PrimeListBenchmark.kt | 44 ++ .../org/jetbrains/ring/StringBenchmark.kt | 60 ++ .../org/jetbrains/ring/SwitchBenchmark.kt | 658 ++++++++++++++++++ .../main/kotlin/org/jetbrains/ring/Utils.kt | 32 + .../jetbrains/ring/WithIndiciesBenchmark.kt | 36 + .../kotlin/org/jetbrains/ring/launcher.kt | 425 +++++++++++ .../main/kotlin/org/jetbrains/ring/zdf-win.kt | 504 ++++++++++++++ settings.gradle | 1 + 33 files changed, 3358 insertions(+) create mode 100644 performance/build.gradle create mode 100644 performance/gradle.properties create mode 100644 performance/src/main/kotlin/main.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/AbstractMethodBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/ClassArrayBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/ClassBaselineBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/ClassListBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/ClassStreamBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/CompanionObjectBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/Data.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/DefaultArgumentBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/ElvisBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/EulerBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/FibonacciBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/InlineBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/IntArrayBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/IntBaselineBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/IntListBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/IntStreamBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/LambdaBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/LoopBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/MatrixMapBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/ParameterNotNullAssertionBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/PrimeListBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/StringBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/SwitchBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/Utils.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/WithIndiciesBenchmark.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/launcher.kt create mode 100644 performance/src/main/kotlin/org/jetbrains/ring/zdf-win.kt diff --git a/.gitignore b/.gitignore index fdef1767c6b..13e5b3fd5ee 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,8 @@ proto/compiler/tests proto/compiler/google/src/google/protobuf/compiler/kotlin/bin proto/compiler/google/src/google/protobuf/compiler/kotlin/protoc +peformance/build + # translator auto generated artifacts kotstd/ll diff --git a/build.gradle b/build.gradle index d71b57c3308..e3d6768496a 100644 --- a/build.gradle +++ b/build.gradle @@ -301,6 +301,12 @@ task bundle(type: (isWindows()) ? Zip : Tar) { } } +task performance { + dependsOn 'dist' + dependsOn ':performance:build' + dependsOn ':performance:run' +} + task clean { doLast { file('dist').traverse(type: FileType.ANY, excludeNameFilter: "dependencies", maxDepth: 0) { diff --git a/performance/build.gradle b/performance/build.gradle new file mode 100644 index 00000000000..48f19562d6d --- /dev/null +++ b/performance/build.gradle @@ -0,0 +1,21 @@ +buildscript { + repositories { + mavenCentral() + maven { + url "https://dl.bintray.com/jetbrains/kotlin-native-dependencies" + } + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-native-gradle-plugin:+" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:+" + } +} + +apply plugin: 'konan' + +konanArtifacts { + Ring { + enableOptimization() + } +} diff --git a/performance/gradle.properties b/performance/gradle.properties new file mode 100644 index 00000000000..325d0e31851 --- /dev/null +++ b/performance/gradle.properties @@ -0,0 +1 @@ +konan.home=../dist \ No newline at end of file diff --git a/performance/src/main/kotlin/main.kt b/performance/src/main/kotlin/main.kt new file mode 100644 index 00000000000..18fa84bbeba --- /dev/null +++ b/performance/src/main/kotlin/main.kt @@ -0,0 +1,14 @@ +import org.jetbrains.ring.Launcher + +fun main(args: Array) { + var numWarmIterations = 0 // Should be 100000 for jdk based run + var numMeasureIterations = 2000 + + if (args.size == 2) { + numWarmIterations = args[0].toInt() + numMeasureIterations = args[1].toInt() + } + + val average = Launcher(numWarmIterations, numMeasureIterations).runBenchmarks() + println("\nRingAverage: $average\n") +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/AbstractMethodBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/AbstractMethodBenchmark.kt new file mode 100644 index 00000000000..6b9ac93b1e4 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/AbstractMethodBenchmark.kt @@ -0,0 +1,36 @@ +package org.jetbrains.ring + +/** + * Created by Mikhail.Glukhikh on 06/03/2015. + * + * A benchmark for a single abstract method based on a string comparison + */ + +open class AbstractMethodBenchmark { + + private val arr: List = zdf_win + private val sequence = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя" + + private val sequenceMap = HashMap() + + init { + var i = 0; + for (ch in sequence) { + sequenceMap[ch] = i++; + } + } + + //Benchmark + fun sortStrings(): Set { + val res = arr.subList(0, if (BENCHMARK_SIZE < arr.size) BENCHMARK_SIZE else arr.size).toSet() + return res + } + + //Benchmark + fun sortStringsWithComparator(): Set { + val res = mutableSetOf() + res.addAll(arr.subList(0, if (BENCHMARK_SIZE < arr.size) BENCHMARK_SIZE else arr.size)) + return res + } +} + diff --git a/performance/src/main/kotlin/org/jetbrains/ring/ClassArrayBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/ClassArrayBenchmark.kt new file mode 100644 index 00000000000..c5ea7ba7952 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/ClassArrayBenchmark.kt @@ -0,0 +1,90 @@ +package org.jetbrains.ring + +open class ClassArrayBenchmark { + private var _data: Array? = null + val data: Array + get() = _data!! + + fun setup() { + val list = ArrayList(BENCHMARK_SIZE) + for (n in classValues(BENCHMARK_SIZE)) + list.add(n) + _data = list.toTypedArray() + } + + //Benchmark + fun copy(): List { + return data.toList() + } + + //Benchmark + fun copyManual(): List { + val list = ArrayList(data.size) + for (item in data) { + list.add(item) + } + return list + } + + //Benchmark + fun filterAndCount(): Int { + return data.filter { filterLoad(it) }.count() + } + + //Benchmark + fun filterAndMap(): List { + return data.filter { filterLoad(it) }.map { mapLoad(it) } + } + + //Benchmark + fun filterAndMapManual(): ArrayList { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) { + val value = mapLoad(it) + list.add(value) + } + } + return list + } + + //Benchmark + fun filter(): List { + return data.filter { filterLoad(it) } + } + + //Benchmark + fun filterManual(): List { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) + list.add(it) + } + return list + } + + //Benchmark + fun countFilteredManual(): Int { + var count = 0 + for (it in data) { + if (filterLoad(it)) + count++ + } + return count + } + + //Benchmark + fun countFiltered(): Int { + return data.count { filterLoad(it) } + } + + //Benchmark + fun countFilteredLocal(): Int { + return data.cnt { filterLoad(it) } + } + + //Benchmark +// fun reduce(): Int { +// return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } +// } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/ClassBaselineBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/ClassBaselineBenchmark.kt new file mode 100644 index 00000000000..f3392feb87b --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/ClassBaselineBenchmark.kt @@ -0,0 +1,61 @@ +package org.jetbrains.ring + +open class ClassBaselineBenchmark { + + //Benchmark + fun consume() { + for (item in 1..BENCHMARK_SIZE) { + Blackhole.consume(Value(item)) + } + } + + //Benchmark + fun consumeField() { + val value = Value(0) + for (item in 1..BENCHMARK_SIZE) { + value.value = item + Blackhole.consume(value) + } + } + + //Benchmark + fun allocateList(): List { + val list = ArrayList(BENCHMARK_SIZE) + return list + } + + //Benchmark + fun allocateArray(): Array { + val list = arrayOfNulls(BENCHMARK_SIZE) + return list + } + + //Benchmark + fun allocateListAndFill(): List { + val list = ArrayList(BENCHMARK_SIZE) + for (item in 1..BENCHMARK_SIZE) { + list.add(Value(item)) + } + return list + } + + //Benchmark + fun allocateListAndWrite(): List { + val value = Value(0) + val list = ArrayList(BENCHMARK_SIZE) + for (item in 1..BENCHMARK_SIZE) { + list.add(value) + } + return list + } + + //Benchmark + fun allocateArrayAndFill(): Array { + val list = arrayOfNulls(BENCHMARK_SIZE) + var index = 0 + for (item in 1..BENCHMARK_SIZE) { + list[index++] = Value(item) + } + return list + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/ClassListBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/ClassListBenchmark.kt new file mode 100644 index 00000000000..0f74bc8a64b --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/ClassListBenchmark.kt @@ -0,0 +1,120 @@ +package org.jetbrains.ring + +open class ClassListBenchmark { + private var _data: ArrayList? = null + val data: ArrayList + get() = _data!! + + fun setup() { + val list = ArrayList(BENCHMARK_SIZE) + for (n in classValues(BENCHMARK_SIZE)) + list.add(n) + _data = list + } + + //Benchmark + fun copy(): List { + return data.toList() + } + + //Benchmark + fun copyManual(): List { + val list = ArrayList(data.size) + for (item in data) { + list.add(item) + } + return list + } + + //Benchmark + fun filterAndCount(): Int { + return data.filter { filterLoad(it) }.count() + } + + //Benchmark + fun filterAndCountWithLambda(): Int { + return data.filter { it.value % 2 == 0 }.count() + } + + //Benchmark + fun filterWithLambda(): List { + return data.filter { it.value % 2 == 0 } + } + + //Benchmark + fun mapWithLambda(): List { + return data.map { it.toString() } + } + + //Benchmark + fun countWithLambda(): Int { + return data.count { it.value % 2 == 0 } + } + + //Benchmark + fun filterAndMapWithLambda(): List { + return data.filter { it.value % 2 == 0 }.map { it.toString() } + } + + //Benchmark + fun filterAndMapWithLambdaAsSequence(): List { + return data.asSequence().filter { it.value % 2 == 0 }.map { it.toString() }.toList() + } + + //Benchmark + fun filterAndMap(): List { + return data.filter { filterLoad(it) }.map { mapLoad(it) } + } + + //Benchmark + fun filterAndMapManual(): ArrayList { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) { + val value = mapLoad(it) + list.add(value) + } + } + return list + } + + //Benchmark + fun filter(): List { + return data.filter { filterLoad(it) } + } + + //Benchmark + fun filterManual(): List { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) + list.add(it) + } + return list + } + + //Benchmark + fun countFilteredManual(): Int { + var count = 0 + for (it in data) { + if (filterLoad(it)) + count++ + } + return count + } + + //Benchmark + fun countFiltered(): Int { + return data.count { filterLoad(it) } + } + + //Benchmark +// fun countFilteredLocal(): Int { +// return data.cnt { filterLoad(it) } +// } + + //Benchmark + fun reduce(): Int { + return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/ClassStreamBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/ClassStreamBenchmark.kt new file mode 100644 index 00000000000..2c4e56d0cc0 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/ClassStreamBenchmark.kt @@ -0,0 +1,85 @@ +package org.jetbrains.ring + +open class ClassStreamBenchmark { + private var _data: Iterable? = null + val data: Iterable + get() = _data!! + + fun setup() { + _data = classValues(BENCHMARK_SIZE) + } + + //Benchmark + fun copy(): List { + return data.asSequence().toList() + } + + //Benchmark + fun copyManual(): List { + val list = ArrayList() + for (item in data.asSequence()) { + list.add(item) + } + return list + } + + //Benchmark + fun filterAndCount(): Int { + return data.asSequence().filter { filterLoad(it) }.count() + } + + //Benchmark + fun filterAndMap() { + for (item in data.asSequence().filter { filterLoad(it) }.map { mapLoad(it) }) + Blackhole.consume(item) + } + + //Benchmark + fun filterAndMapManual() { + for (it in data.asSequence()) { + if (filterLoad(it)) { + val item = mapLoad(it) + Blackhole.consume(item) + } + } + } + + //Benchmark + fun filter() { + for (item in data.asSequence().filter { filterLoad(it) }) + Blackhole.consume(item) + } + + //Benchmark + fun filterManual(){ + for (it in data.asSequence()) { + if (filterLoad(it)) + Blackhole.consume(it) + } + } + + //Benchmark + fun countFilteredManual(): Int { + var count = 0 + for (it in data.asSequence()) { + if (filterLoad(it)) + count++ + } + return count + } + + //Benchmark + fun countFiltered(): Int { + return data.asSequence().count { filterLoad(it) } + } + + //Benchmark +// fun countFilteredLocal(): Int { +// return data.asSequence().cnt { filterLoad(it) } +// } + + //Benchmark + fun reduce(): Int { + return data.asSequence().fold(0) {acc, it -> if (filterLoad(it)) acc + 1 else acc } + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/CompanionObjectBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/CompanionObjectBenchmark.kt new file mode 100644 index 00000000000..f721e40a867 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/CompanionObjectBenchmark.kt @@ -0,0 +1,23 @@ +package org.jetbrains.ring + +open class CompanionObjectBenchmark { + //Benchmark + fun invokeRegularFunction() { + regularCompanionObjectFunction("") + } + + //Benchmark + fun invokeJvmStaticFunction() { + staticCompanionObjectFunction("") + } + + companion object { + fun regularCompanionObjectFunction(o: Any): Any { + return o + } + + fun staticCompanionObjectFunction(o: Any): Any { + return o + } + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/Data.kt b/performance/src/main/kotlin/org/jetbrains/ring/Data.kt new file mode 100644 index 00000000000..d9b7531b7b7 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/Data.kt @@ -0,0 +1,84 @@ +package org.jetbrains.ring + +fun classValues(size: Int): Iterable { + return intValues(size).map { Value(it) } +} + +fun stringValues(size: Int): Iterable { + return intValues(size).map { it.toString() } +} + +fun intValues(size: Int): Iterable { + return 1..size +} + +open class Value(var value: Int) { + val text = value.toString().reversed() +} + +fun filterLoad(v: Value): Boolean { + return v.value.toString() in v.text +} + +fun mapLoad(v: Value): String = v.text.reversed() + +fun filterLoad(v: Int): Boolean { + return v.toString() in "0123456789" +} + +fun mapLoad(v: Int): String = v.toString() + +fun filterSome(v: Int): Boolean = v % 7 == 0 || v % 11 == 0 + +fun filterPrime(v: Int): Boolean { + if (v <= 1) + return false + if (v <= 3) + return true + if (v % 2 == 0) + return false + var i = 3 + while (i*i <= v) { + if (v % i == 0) + return false + i += 2 + } + return true +} + +inline fun Array.cnt(predicate: (Value) -> Boolean): Int { + var count = 0 + for (element in this) { + if (predicate(element)) + count++ + } + return count +} + +inline fun IntArray.cnt(predicate: (Int) -> Boolean): Int { + var count = 0 + for (element in this) { + if (predicate(element)) + count++ + } + return count +} + +inline fun Iterable.cnt(predicate: (Int) -> Boolean): Int { + var count = 0 + for (element in this) { + if (predicate(element)) + count++ + } + return count +} + +inline fun Sequence.cnt(predicate: (Int) -> Boolean): Int { + var count = 0 + for (element in this) { + if (predicate(element)) + count++ + } + return count +} + diff --git a/performance/src/main/kotlin/org/jetbrains/ring/DefaultArgumentBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/DefaultArgumentBenchmark.kt new file mode 100644 index 00000000000..8254b1f126c --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/DefaultArgumentBenchmark.kt @@ -0,0 +1,65 @@ +package org.jetbrains.ring + +/** + * Created by Mikhail.Glukhikh on 10/03/2015. + * + * Tests performance for function calls with default parameters + */ +open class DefaultArgumentBenchmark { + private var arg = 0 + + fun setup() { + arg = Random.nextInt() + } + + + fun sumTwo(first: Int, second: Int = 0): Int { + return first + second + } + + + fun sumFour(first: Int, second: Int = 0, third: Int = 1, fourth: Int = third): Int { + return first + second + third + fourth + } + + + fun sumEight(first: Int, second: Int = 0, third: Int = 1, fourth: Int = third, + fifth: Int = fourth, sixth: Int = fifth, seventh: Int = second, eighth: Int = seventh): Int { + return first + second + third + fourth + fifth + sixth + seventh + eighth + } + + + //Benchmark + fun testOneOfTwo() { + sumTwo(arg) + } + + + //Benchmark + fun testTwoOfTwo() { + sumTwo(arg, arg) + } + + //Benchmark + fun testOneOfFour() { + sumFour(arg) + } + + + //Benchmark + fun testFourOfFour() { + sumFour(arg, arg, arg, arg) + } + + + //Benchmark + fun testOneOfEight() { + sumEight(arg) + } + + + //Benchmark + fun testEightOfEight() { + sumEight(arg, arg, arg, arg, arg, arg, arg, arg) + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/ElvisBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/ElvisBenchmark.kt new file mode 100644 index 00000000000..ab775c034be --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/ElvisBenchmark.kt @@ -0,0 +1,21 @@ +package org.jetbrains.ring + +open class ElvisBenchmark { + + class Value(var value: Int) + + var array : Array = arrayOf() + + fun setup() { + array = Array(BENCHMARK_SIZE) { + if (Random.nextInt(BENCHMARK_SIZE) < BENCHMARK_SIZE / 10) null else Value(Random.nextInt()) + } + } + + //Benchmark + fun testElvis() { + for (obj in array) { + Blackhole.consume(obj?.value ?: 0) + } + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/EulerBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/EulerBenchmark.kt new file mode 100644 index 00000000000..a21e0f09af9 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/EulerBenchmark.kt @@ -0,0 +1,199 @@ +package org.jetbrains.ring + +fun fibonacci(): Sequence { + var a = 0 + var b = 1 + fun next(): Int { + val res = a + b + a = b + b = res + return res + } + return generateSequence { next() } +} + +fun Any.isPalindrome() = toString() == toString().reversed() + +inline fun IntRange.sum(predicate: (Int) -> Boolean): Int { + var sum = 0 + for (i in this) if (predicate(i)) sum += i + return sum +} + +inline fun Sequence.sum(predicate: (Int) -> Boolean): Int { + var sum = 0 + for (i in this) if (predicate(i)) sum += i + return sum +} + +/** + * A class tests decisions of various Euler problems + * + * NB: all tests here work slower than Java, probably because of all these functional wrappers + */ +open class EulerBenchmark { + + //Benchmark + fun problem1bySequence() = (1..BENCHMARK_SIZE).asSequence().sum( { it % 3 == 0 || it % 5 == 0} ) + + //Benchmark + fun problem1() = (1..BENCHMARK_SIZE).sum( { it % 3 == 0 || it % 5 == 0} ) + + //Benchmark + fun problem2() = fibonacci().takeWhile { it < BENCHMARK_SIZE }.sum { it % 2 == 0 } + + //Benchmark + fun problem4(): Long { + val s: Long = BENCHMARK_SIZE.toLong() + val maxLimit = (s-1)*(s-1) + val minLimit = (s/10)*(s/10) + val maxDiv = BENCHMARK_SIZE-1 + val minDiv = BENCHMARK_SIZE/10 + for (i in maxLimit downTo minLimit) { + if (!i.isPalindrome()) continue; + for (j in minDiv..maxDiv) { + if (i % j == 0L) { + val res = i / j + // Without toLong() here we have a real nightmare... + // in is resolved to Iterable.contains(Long) + // which has O(N) complexity and always gives false + // See KT-6978, KT-6950, KT-6361 + if (res in minDiv.toLong()..maxDiv.toLong()) { + return i + } + } + } + } + return -1 + } + + private val veryLongNumber = """ + 73167176531330624919225119674426574742355349194934 + 96983520312774506326239578318016984801869478851843 + 85861560789112949495459501737958331952853208805511 + 12540698747158523863050715693290963295227443043557 + 66896648950445244523161731856403098711121722383113 + 62229893423380308135336276614282806444486645238749 + 30358907296290491560440772390713810515859307960866 + 70172427121883998797908792274921901699720888093776 + 65727333001053367881220235421809751254540594752243 + 52584907711670556013604839586446706324415722155397 + 53697817977846174064955149290862569321978468622482 + 83972241375657056057490261407972968652414535100474 + 82166370484403199890008895243450658541227588666881 + 16427171479924442928230863465674813919123162824586 + 17866458359124566529476545682848912883142607690042 + 24219022671055626321111109370544217506941658960408 + 07198403850962455444362981230987879927244284909188 + 84580156166097919133875499200524063689912560717606 + 05886116467109405077541002256983155200055935729725 + 71636269561882670428252483600823257530420752963450 + """ + + + //Benchmark + fun problem8(): Long { + val productSize = when(BENCHMARK_SIZE) { + in 1..10 -> 4 + in 11..1000 -> 8 + else -> 13 + } + val digits: MutableList = ArrayList() + for (digit in veryLongNumber) { + if (digit in '0'..'9') { + digits.add(digit.toInt() - '0'.toInt()) + } + } + var largest = 0L + for (i in 0..digits.size -productSize-1) { + var product = 1L + for (j in 0..productSize-1) { + product *= digits[i+j] + } + if (product > largest) largest = product + } + return largest + } + + + //Benchmark + fun problem9(): Long { + val BENCHMARK_SIZE = BENCHMARK_SIZE // Looks awful but removes all implicit getSize() calls + for (c in BENCHMARK_SIZE/3..BENCHMARK_SIZE-3) { + val c2 = c.toLong() * c.toLong() + for (b in (BENCHMARK_SIZE-c)/2..c-1) { + if (b+c >= BENCHMARK_SIZE) + break + val a = BENCHMARK_SIZE - b - c + if (a >= b) + continue + val b2 = b.toLong() * b.toLong() + val a2 = a.toLong() * a.toLong() + if (c2 == b2 + a2) { + return a.toLong() * b.toLong() * c.toLong() + } + } + } + return -1L + } + + data class Children(val left: Int, val right: Int) + + + //Benchmark + fun problem14(): List { + // Simplified problem is solved here: it's not allowed to leave the interval [0..BENCHMARK_SIZE) inside a number chain + val BENCHMARK_SIZE = BENCHMARK_SIZE + // Build a tree + // index is produced from first & second + val tree = Array(BENCHMARK_SIZE, { i -> Children(i*2, if (i>4 && (i+2) % 6 == 0) (i-1)/3 else 0)}) + // Find longest chain by DFS + fun dfs(begin: Int): List { + if (begin == 0 || begin >= BENCHMARK_SIZE) + return listOf() + val left = dfs(tree[begin].left) + val right = dfs(tree[begin].right) + return listOf(begin) + if (left.size > right.size) left else right + } + return dfs(1) + } + + data class Way(val length: Int, val next: Int) + + + //Benchmark + fun problem14full(): List { + val BENCHMARK_SIZE = BENCHMARK_SIZE + // Previous achievements: map (number) -> (length, next) + val map: MutableMap = HashMap() + // Starting point + map.put(1, Way(0, 0)) + // Check all other numbers + var bestNum = 0 + var bestLen = 0 + fun go(begin: Int): Way { + val res = map[begin] + if (res != null) + return res + val next = if (begin % 2 == 0) begin/2 else 3*begin+1 + val childRes = go(next) + val myRes = Way(childRes.length + 1, next) + map[begin] = myRes + return myRes + } + for (i in 2..BENCHMARK_SIZE-1) { + val res = go(i) + if (res.length > bestLen) { + bestLen = res.length + bestNum = i + } + } + fun unroll(begin: Int): List { + if (begin == 0) + return listOf() + val next = map[begin]?.next ?: 0 + return listOf(begin) + unroll(next) + } + return unroll(bestNum) + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/FibonacciBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/FibonacciBenchmark.kt new file mode 100644 index 00000000000..7540720455c --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/FibonacciBenchmark.kt @@ -0,0 +1,70 @@ +package org.jetbrains.ring + +/** + * This test checks work with long numbers using Fibonacci sequence + * + * NB: all three tests here work CRITICALLY (x4...x6) slower than their Java equivalents + * The reason is iteration on a progression formed as max downTo min or min..max step s. + * In case of a range min..max primitive types are used by the Kotlin compiler, + * but when we have a progression it's used directly with its iterator and so. + */ + +open class FibonacciBenchmark { + + //Benchmark + fun calcClassic(): Long { + var a = 1L + var b = 2L + val size = BENCHMARK_SIZE + for (i in 0..size-1) { + val next = a + b + a = b + b = next + } + return b + } + + //Benchmark + fun calc(): Long { + // This test works CRITICALLY slower compared with java equivalent (05.03.2015) + var a = 1L + var b = 2L + // Probably for with downTo is the reason of slowness + for (i in BENCHMARK_SIZE downTo 1) { + val next = a + b + a = b + b = next + } + return b + } + + //Benchmark + fun calcWithProgression(): Long { + // This test works CRITICALLY slower compared with java equivalent (05.03.2015) + var a = 1L + var b = 2L + // Probably for with step is the reason of slowness + for (i in 1..2*BENCHMARK_SIZE-1 step 2) { + val next = a + b + a = b + b = next + } + return b + } + + //Benchmark + fun calcSquare(): Long { + // This test works CRITICALLY slower compared with java equivalent (05.03.2015) + var a = 1L + var b = 2L + val s = BENCHMARK_SIZE.toLong() + val limit = s*s + // Probably for with downTo is the reason of slowness + for (i in limit downTo 1) { + val next = a + b + a = b + b = next + } + return b + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/InlineBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/InlineBenchmark.kt new file mode 100644 index 00000000000..00ed4666922 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/InlineBenchmark.kt @@ -0,0 +1,57 @@ +package org.jetbrains.ring + +fun load(value: Int, size: Int): Int { + var acc = 0 + for (i in 0..size) { + acc = acc xor value.hashCode() + } + return acc +} + +inline fun loadInline(value: Int, size: Int): Int { + var acc = 0 + for (i in 0..size) { + acc = acc xor value.hashCode() + } + return acc +} + +fun loadGeneric(value: T, size: Int): Int { + var acc = 0 + for (i in 0..size) { + acc = acc xor value.hashCode() + } + return acc +} + +inline fun loadGenericInline(value: T, size: Int): Int { + var acc = 0 + for (i in 0..size) { + acc = acc xor value.hashCode() + } + return acc +} + +open class InlineBenchmark { + private var value = 2138476523 + + //Benchmark + fun calculate(): Int { + return load(value, BENCHMARK_SIZE) + } + + //Benchmark + fun calculateInline(): Int { + return loadInline(value, BENCHMARK_SIZE) + } + + //Benchmark + fun calculateGeneric(): Int { + return loadGeneric(value, BENCHMARK_SIZE) + } + + //Benchmark + fun calculateGenericInline(): Int { + return loadGenericInline(value, BENCHMARK_SIZE) + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/IntArrayBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/IntArrayBenchmark.kt new file mode 100644 index 00000000000..33a28402f6f --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/IntArrayBenchmark.kt @@ -0,0 +1,155 @@ +package org.jetbrains.ring + +open class IntArrayBenchmark { + private var _data: IntArray? = null + val data: IntArray + get() = _data!! + + fun setup() { + val list = IntArray(BENCHMARK_SIZE) + var index = 0 + for (n in intValues(BENCHMARK_SIZE)) + list[index++] = n + _data = list + } + + //Benchmark + fun copy(): List { + return data.toList() + } + + //Benchmark + fun copyManual(): ArrayList { + val list = ArrayList(data.size) + for (item in data) { + list.add(item) + } + return list + } + + //Benchmark + fun filterAndCount(): Int { + return data.filter { filterLoad(it) }.count() + } + + //Benchmark + fun filterSomeAndCount(): Int { + return data.filter { filterSome(it) }.count() + } + + //Benchmark + fun filterAndMap(): List { + return data.filter { filterLoad(it) }.map { mapLoad(it) } + } + + //Benchmark + fun filterAndMapManual(): ArrayList { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) { + val value = mapLoad(it) + list.add(value) + } + } + return list + } + + //Benchmark + fun filter(): List { + return data.filter { filterLoad(it) } + } + + //Benchmark + fun filterSome(): List { + return data.filter { filterSome(it) } + } + + //Benchmark + fun filterPrime(): List { + return data.filter { filterPrime(it) } + } + + //Benchmark + fun filterManual(): ArrayList { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) + list.add(it) + } + return list + } + + //Benchmark + fun filterSomeManual(): ArrayList { + val list = ArrayList() + for (it in data) { + if (filterSome(it)) + list.add(it) + } + return list + } + + //Benchmark + fun countFilteredManual(): Int { + var count = 0 + for (it in data) { + if (filterLoad(it)) + count++ + } + return count + } + + //Benchmark + fun countFilteredSomeManual(): Int { + var count = 0 + for (it in data) { + if (filterSome(it)) + count++ + } + return count + } + + //Benchmark + fun countFilteredPrimeManual(): Int { + var count = 0 + for (it in data) { + if (filterPrime(it)) + count++ + } + return count + } + + + //Benchmark + fun countFiltered(): Int { + return data.count { filterLoad(it) } + } + + //Benchmark + fun countFilteredSome(): Int { + return data.count { filterSome(it) } + } + + //Benchmark + fun countFilteredPrime(): Int { + val res = data.count { filterPrime(it) } + //println(res) + return res + } + + //Benchmark + fun countFilteredLocal(): Int { + return data.cnt { filterLoad(it) } + } + + //Benchmark + fun countFilteredSomeLocal(): Int { + return data.cnt { filterSome(it) } + } + + //Benchmark + fun reduce(): Int { + return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } + } +} + diff --git a/performance/src/main/kotlin/org/jetbrains/ring/IntBaselineBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/IntBaselineBenchmark.kt new file mode 100644 index 00000000000..3a06d9a619e --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/IntBaselineBenchmark.kt @@ -0,0 +1,43 @@ +package org.jetbrains.ring + + +open class IntBaselineBenchmark { + + //Benchmark + fun consume() { + for (item in 1..BENCHMARK_SIZE) { + Blackhole.consume(item) + } + } + + //Benchmark + fun allocateList(): List { + val list = ArrayList(BENCHMARK_SIZE) + return list + } + + //Benchmark + fun allocateArray(): IntArray { + val list = IntArray(BENCHMARK_SIZE) + return list + } + + //Benchmark + fun allocateListAndFill(): List { + val list = ArrayList(BENCHMARK_SIZE) + for (item in 1..BENCHMARK_SIZE) { + list.add(item) + } + return list + } + + //Benchmark + fun allocateArrayAndFill(): IntArray { + var index = 0 + val list = IntArray(BENCHMARK_SIZE) + for (item in 1..BENCHMARK_SIZE) { + list[index++] = item + } + return list + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/IntListBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/IntListBenchmark.kt new file mode 100644 index 00000000000..2d19b638889 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/IntListBenchmark.kt @@ -0,0 +1,90 @@ +package org.jetbrains.ring + +open class IntListBenchmark { + private var _data: List? = null + val data: List + get() = _data!! + + fun setup() { + val list = ArrayList(BENCHMARK_SIZE) + for (n in intValues(BENCHMARK_SIZE)) + list.add(n) + _data = list + } + + //Benchmark + fun copy(): List { + return data.toList() + } + + //Benchmark + fun copyManual(): List { + val list = ArrayList(data.size) + for (item in data) { + list.add(item) + } + return list + } + + //Benchmark + fun filterAndCount(): Int { + return data.filter { filterLoad(it) }.count() + } + + //Benchmark + fun filterAndMap(): List { + return data.filter { filterLoad(it) }.map { mapLoad(it) } + } + + //Benchmark + fun filterAndMapManual(): ArrayList { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) { + val value = mapLoad(it) + list.add(value) + } + } + return list + } + + //Benchmark + fun filter(): List { + return data.filter { filterLoad(it) } + } + + //Benchmark + fun filterManual(): List { + val list = ArrayList() + for (it in data) { + if (filterLoad(it)) + list.add(it) + } + return list + } + + //Benchmark + fun countFilteredManual(): Int { + var count = 0 + for (it in data) { + if (filterLoad(it)) + count++ + } + return count + } + + //Benchmark + fun countFiltered(): Int { + return data.count { filterLoad(it) } + } + + //Benchmark + fun countFilteredLocal(): Int { + return data.cnt { filterLoad(it) } + } + + //Benchmark + fun reduce(): Int { + return data.fold(0) { acc, it -> if (filterLoad(it)) acc + 1 else acc } + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/IntStreamBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/IntStreamBenchmark.kt new file mode 100644 index 00000000000..748d0fb1958 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/IntStreamBenchmark.kt @@ -0,0 +1,85 @@ +package org.jetbrains.ring + +open class IntStreamBenchmark { + private var _data: Iterable? = null + val data: Iterable + get() = _data!! + + fun setup() { + _data = intValues(BENCHMARK_SIZE) + } + + //Benchmark + fun copy(): List { + return data.asSequence().toList() + } + + //Benchmark + fun copyManual(): List { + val list = ArrayList() + for (item in data.asSequence()) { + list.add(item) + } + return list + } + + //Benchmark + fun filterAndCount(): Int { + return data.asSequence().filter { filterLoad(it) }.count() + } + + //Benchmark + fun filterAndMap() { + for (item in data.asSequence().filter { filterLoad(it) }.map { mapLoad(it) }) + Blackhole.consume(item) + } + + //Benchmark + fun filterAndMapManual() { + for (it in data.asSequence()) { + if (filterLoad(it)) { + val item = mapLoad(it) + Blackhole.consume(item) + } + } + } + + //Benchmark + fun filter() { + for (item in data.asSequence().filter { filterLoad(it) }) + Blackhole.consume(item) + } + + //Benchmark + fun filterManual(){ + for (it in data.asSequence()) { + if (filterLoad(it)) + Blackhole.consume(it) + } + } + + //Benchmark + fun countFilteredManual(): Int { + var count = 0 + for (it in data.asSequence()) { + if (filterLoad(it)) + count++ + } + return count + } + + //Benchmark + fun countFiltered(): Int { + return data.asSequence().count { filterLoad(it) } + } + + //Benchmark + fun countFilteredLocal(): Int { + return data.asSequence().cnt { filterLoad(it) } + } + + //Benchmark + fun reduce(): Int { + return data.asSequence().fold(0) {acc, it -> if (filterLoad(it)) acc + 1 else acc } + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/LambdaBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/LambdaBenchmark.kt new file mode 100644 index 00000000000..ff8d82fee48 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/LambdaBenchmark.kt @@ -0,0 +1,90 @@ +package org.jetbrains.ring + +var globalAddendum = 0 + +open class LambdaBenchmark { + private fun runLambda(x: () -> T): T = x() + private fun runLambdaNoInline(x: () -> T): T = x() + + fun setup() { + globalAddendum = Random.nextInt(20) + } + + //Benchmark + fun noncapturingLambda(): Int { + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + x += runLambda { globalAddendum } + } + return x + } + + //Benchmark + fun noncapturingLambdaNoInline(): Int { + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + x += runLambdaNoInline { globalAddendum } + } + return x + } + + //Benchmark + fun capturingLambda(): Int { + val addendum = globalAddendum + 1 + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + x += runLambda { addendum } + } + return x + } + + //Benchmark + fun capturingLambdaNoInline(): Int { + val addendum = globalAddendum + 1 + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + x += runLambdaNoInline { addendum } + } + return x + } + + //Benchmark + fun mutatingLambda(): Int { + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + runLambda { x += globalAddendum } + } + return x + } + + //Benchmark + fun mutatingLambdaNoInline(): Int { + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + runLambdaNoInline { x += globalAddendum } + } + return x + } + + //Benchmark + fun methodReference(): Int { + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + x += runLambda(::referenced) + } + return x + } + + //Benchmark + fun methodReferenceNoInline(): Int { + var x: Int = 0 + for (i in 0..BENCHMARK_SIZE) { + x += runLambdaNoInline(::referenced) + } + return x + } +} + +private fun referenced(): Int { + return globalAddendum +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/LoopBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/LoopBenchmark.kt new file mode 100644 index 00000000000..03c660510b8 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/LoopBenchmark.kt @@ -0,0 +1,62 @@ +package org.jetbrains.ring + +open class LoopBenchmark { + lateinit var arrayList: List + lateinit var array: Array + + fun setup() { + val list = ArrayList(BENCHMARK_SIZE) + for (n in classValues(BENCHMARK_SIZE)) + list.add(n) + arrayList = list + array = list.toTypedArray() + } + + //Benchmark + fun arrayLoop() { + for (x in array) { + Blackhole.consume(x) + } + } + + //Benchmark + fun arrayIndexLoop() { + for (i in array.indices) { + Blackhole.consume(array[i]) + } + } + + //Benchmark + fun rangeLoop() { + for (i in 0..BENCHMARK_SIZE) { + Blackhole.consume(i) + } + } + + //Benchmark + fun arrayListLoop() { + for (x in arrayList) { + Blackhole.consume(x) + } + } + + //Benchmark + fun arrayWhileLoop() { + var i = 0 + val s = array.size + while (i < s) { + Blackhole.consume(array[i]) + i++ + } + } + + //Benchmark + fun arrayForeachLoop() { + array.forEach { Blackhole.consume(it) } + } + + //Benchmark + fun arrayListForeachLoop() { + arrayList.forEach { Blackhole.consume(it) } + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/MatrixMapBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/MatrixMapBenchmark.kt new file mode 100644 index 00000000000..02d77fdb7de --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/MatrixMapBenchmark.kt @@ -0,0 +1,57 @@ +package org.jetbrains.ring + +import org.jetbrains.ring.BENCHMARK_SIZE + +/** + * This class emulates matrix behaviour using a hash map as its implementation + */ +class KMatrix internal constructor(val rows: Int, val columns: Int) { + private val matrix: MutableMap, Double> = HashMap(); + + init { + for (row in 0..rows-1) { + for (col in 0..columns-1) { + matrix.put(Pair(row, col), Random.nextDouble()) + } + } + } + + fun get(row: Int, col: Int): Double { + return get(Pair(row, col)) + } + + fun get(pair: Pair): Double { + return matrix.getOrElse(pair, { 0.0 }) + } + + fun put(pair: Pair, elem: Double) { + matrix.put(pair, elem) + } + + operator fun plusAssign(other: KMatrix) { + for (entry in matrix.entries) { + put(entry.key, entry.value + other.get(entry.key)) + } + } +} + +/** + * This class tests hash map performance + */ +open class MatrixMapBenchmark { + + //Benchmark + fun add(): KMatrix { + var rows = BENCHMARK_SIZE + var cols = 1 + while (rows > cols) { + rows /= 2 + cols *= 2 + } + val a = KMatrix(rows, cols) + val b = KMatrix(rows, cols) + a += b + return a + } + +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/ParameterNotNullAssertionBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/ParameterNotNullAssertionBenchmark.kt new file mode 100644 index 00000000000..85c24518426 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/ParameterNotNullAssertionBenchmark.kt @@ -0,0 +1,61 @@ +package org.jetbrains.ring + +val OBJ = Any() + +open class ParameterNotNullAssertionBenchmark { + + fun methodWithOneNotnullParameter(p: Any): Any { + return p + } + + private fun privateMethodWithOneNotnullParameter(p: Any): Any { + return p + } + + fun methodWithTwoNotnullParameters(p: Any, p2: Any): Any { + return p + } + + private fun privateMethodWithTwoNotnullParameters(p: Any, p2: Any): Any { + return p + } + + fun methodWithEightNotnullParameters(p: Any, p2: Any, p3: Any, p4: Any, p5: Any, p6: Any, p7: Any, p8: Any): Any { + return p + } + + private fun privateMethodWithEightNotnullParameters(p: Any, p2: Any, p3: Any, p4: Any, p5: Any, p6: Any, p7: Any, p8: Any): Any { + return p + } + + //Benchmark + fun invokeOneArgWithNullCheck(): Any { + return methodWithOneNotnullParameter(OBJ) + } + + //Benchmark + fun invokeOneArgWithoutNullCheck(): Any { + return privateMethodWithOneNotnullParameter(OBJ) + } + + //Benchmark + fun invokeTwoArgsWithNullCheck(): Any { + return methodWithTwoNotnullParameters(OBJ, OBJ) + } + + //Benchmark + fun invokeTwoArgsWithoutNullCheck(): Any { + return privateMethodWithTwoNotnullParameters(OBJ, OBJ) + } + + //Benchmark + fun invokeEightArgsWithNullCheck(): Any { + return methodWithEightNotnullParameters(OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ) + } + + //Benchmark + fun invokeEightArgsWithoutNullCheck(): Any { + return privateMethodWithEightNotnullParameters(OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ, OBJ) + } +} + diff --git a/performance/src/main/kotlin/org/jetbrains/ring/PrimeListBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/PrimeListBenchmark.kt new file mode 100644 index 00000000000..41d50543474 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/PrimeListBenchmark.kt @@ -0,0 +1,44 @@ +package org.jetbrains.ring + +/** + * This class tests linked list performance + * using prime number calculation algorithms + * + * @author Mikhail Glukhikh + */ +open class PrimeListBenchmark { + private var primes: MutableList = mutableListOf() + + //Benchmark + fun calcDirect() { + primes.clear() + primes.add(2) + var i = 3 + while (i <= BENCHMARK_SIZE) { + var simple = true + for (prime in primes) { + if (prime * prime > i) + break + if (i % prime == 0) { + simple = false + break + } + } + if (simple) + primes.add(i) + i += 2 + } + } + + //Benchmark + fun calcEratosthenes() { + primes.clear() + primes.addAll(2..BENCHMARK_SIZE) + var i = 0 + while (i < primes.size) { + val divisor = primes[i] + primes.removeAll { it -> it > divisor && it % divisor == 0 } + i++ + } + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/StringBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/StringBenchmark.kt new file mode 100644 index 00000000000..c967af97fbc --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/StringBenchmark.kt @@ -0,0 +1,60 @@ +package org.jetbrains.ring + +open class StringBenchmark { + private var _data: ArrayList? = null + val data: ArrayList + get() = _data!! + var csv: String = "" + + fun setup() { + val list = ArrayList(BENCHMARK_SIZE) + for (n in stringValues(BENCHMARK_SIZE)) + list.add(n) + _data = list + csv = "" + for (i in 1..BENCHMARK_SIZE-1) { + val elem = Random.nextDouble() + csv += elem + csv += "," + } + csv += 0.0 + } + + //Benchmark + open fun stringConcat(): String? { + var string: String = "" + for (it in data) string += it + return string + } + + //Benchmark + open fun stringConcatNullable(): String? { + var string: String? = "" + for (it in data) string += it + return string + } + + //Benchmark + open fun stringBuilderConcat(): String { + var string : StringBuilder = StringBuilder("") + for (it in data) string.append(it) + return string.toString() + } + + //Benchmark + open fun stringBuilderConcatNullable(): String { + var string : StringBuilder? = StringBuilder("") + for (it in data) string?.append(it) + return string.toString() + } + + //Benchmark + open fun summarizeSplittedCsv(): Double { + val fields = csv.split(",") + var sum = 0.0 + for (field in fields) { + sum += field.toDouble() + } + return sum + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/SwitchBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/SwitchBenchmark.kt new file mode 100644 index 00000000000..abb25d8684f --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/SwitchBenchmark.kt @@ -0,0 +1,658 @@ +package org.jetbrains.ring + +val SPARSE_SWITCH_CASES = intArrayOf(11, 29, 47, 71, 103, + 149, 175, 227, 263, 307, + 361, 487, 563, 617, 677, + 751, 823, 883, 967, 1031) + +const val V1 = 1 +const val V2 = 2 +const val V3 = 3 +const val V4 = 4 +const val V5 = 5 +const val V6 = 6 +const val V7 = 7 +const val V8 = 8 +const val V9 = 9 +const val V10 = 10 +const val V11 = 11 +const val V12 = 12 +const val V13 = 13 +const val V14 = 14 +const val V15 = 15 +const val V16 = 16 +const val V17 = 17 +const val V18 = 18 +const val V19 = 19 +const val V20 = 20 + + +object Numbers { + const val V1 = 1 + const val V2 = 2 + const val V3 = 3 + const val V4 = 4 + const val V5 = 5 + const val V6 = 6 + const val V7 = 7 + const val V8 = 8 + const val V9 = 9 + const val V10 = 10 + const val V11 = 11 + const val V12 = 12 + const val V13 = 13 + const val V14 = 14 + const val V15 = 15 + const val V16 = 16 + const val V17 = 17 + const val V18 = 18 + const val V19 = 19 + const val V20 = 20 +} + +var VV1 = 1 +var VV2 = 2 +var VV3 = 3 +var VV4 = 4 +var VV5 = 5 +var VV6 = 6 +var VV7 = 7 +var VV8 = 8 +var VV9 = 9 +var VV10 = 10 +var VV11 = 11 +var VV12 = 12 +var VV13 = 13 +var VV14 = 14 +var VV15 = 15 +var VV16 = 16 +var VV17 = 17 +var VV18 = 18 +var VV19 = 19 +var VV20 = 20 + +open class SwitchBenchmark { + fun sparseIntSwitch(u : Int) : Int { + var t : Int + when (u) { + 11 -> { + t = 1 + } + 29 -> { + t = 2 + } + 47 -> { + t = 3 + } + 71 -> { + t = 4 + } + 103 -> { + t = 5 + } + 149 -> { + t = 6 + } + 175 -> { + t = 7 + } + 227 -> { + t = 1 + } + 263 -> { + t = 9 + } + 307 -> { + t = 1 + } + 361 -> { + t = 2 + } + 487 -> { + t = 3 + } + 563 -> { + t = 4 + } + 617 -> { + t = 4 + } + 677 -> { + t = 4 + } + 751 -> { + t = 435 + } + 823 -> { + t = 31 + } + 883 -> { + t = 1 + } + 967 -> { + t = 1 + } + 1031 -> { + t = 1 + } + 20 -> { + t = 1 + } + else -> { + t = 5 + } + } + return t + } + + fun denseIntSwitch(u : Int) : Int { + var t : Int + when (u) { + 1 -> { + t = 1 + } + -1 -> { + t = 2 + } + 2 -> { + t = 3 + } + 3 -> { + t = 4 + } + 4 -> { + t = 5 + } + 5 -> { + t = 6 + } + 6 -> { + t = 7 + } + 7 -> { + t = 1 + } + 8 -> { + t = 9 + } + 9 -> { + t = 1 + } + 10 -> { + t = 2 + } + 11 -> { + t = 3 + } + 12 -> { + t = 4 + } + 13 -> { + t = 4 + } + 14 -> { + t = 4 + } + 15 -> { + t = 435 + } + 16 -> { + t = 31 + } + 17 -> { + t = 1 + } + 18 -> { + t = 1 + } + 19 -> { + t = 1 + } + 20 -> { + t = 1 + } + else -> { + t = 5 + } + } + return t + } + + fun constSwitch(u : Int) : Int { + var t : Int + when (u) { + V1 -> { + t = 1 + } + V2 -> { + t = 3 + } + V3 -> { + t = 4 + } + V4 -> { + t = 5 + } + V5 -> { + t = 6 + } + V6 -> { + t = 7 + } + V7 -> { + t = 1 + } + V8 -> { + t = 9 + } + V9 -> { + t = 1 + } + V10 -> { + t = 2 + } + V11 -> { + t = 3 + } + V12 -> { + t = 4 + } + V13 -> { + t = 4 + } + V14 -> { + t = 4 + } + V15 -> { + t = 435 + } + V16 -> { + t = 31 + } + V17 -> { + t = 1 + } + V18 -> { + t = 1 + } + V19 -> { + t = 1 + } + V20 -> { + t = 1 + } + else -> { + t = 5 + } + } + return t + } + + fun objConstSwitch(u : Int) : Int { + var t : Int + when (u) { + Numbers.V1 -> { + t = 1 + } + Numbers.V2 -> { + t = 3 + } + Numbers.V3 -> { + t = 4 + } + Numbers.V4 -> { + t = 5 + } + Numbers.V5 -> { + t = 6 + } + Numbers.V6 -> { + t = 7 + } + Numbers.V7 -> { + t = 1 + } + Numbers.V8 -> { + t = 9 + } + Numbers.V9 -> { + t = 1 + } + Numbers.V10 -> { + t = 2 + } + Numbers.V11 -> { + t = 3 + } + Numbers.V12 -> { + t = 4 + } + Numbers.V13 -> { + t = 4 + } + Numbers.V14 -> { + t = 4 + } + Numbers.V15 -> { + t = 435 + } + Numbers.V16 -> { + t = 31 + } + Numbers.V17 -> { + t = 1 + } + Numbers.V18 -> { + t = 1 + } + Numbers.V19 -> { + t = 1 + } + Numbers.V20 -> { + t = 1 + } + else -> { + t = 5 + } + } + return t + } + + fun varSwitch(u : Int) : Int { + var t : Int + when (u) { + VV1 -> { + t = 1 + } + VV2 -> { + t = 3 + } + VV3 -> { + t = 4 + } + VV4 -> { + t = 5 + } + VV5 -> { + t = 6 + } + VV6 -> { + t = 7 + } + VV7 -> { + t = 1 + } + VV8 -> { + t = 9 + } + VV9 -> { + t = 1 + } + VV10 -> { + t = 2 + } + VV11 -> { + t = 3 + } + VV12 -> { + t = 4 + } + VV13 -> { + t = 4 + } + VV14 -> { + t = 4 + } + VV15 -> { + t = 435 + } + VV16 -> { + t = 31 + } + VV17 -> { + t = 1 + } + VV18 -> { + t = 1 + } + VV19 -> { + t = 1 + } + VV20 -> { + t = 1 + } + else -> { + t = 5 + } + } + return t + } + + private fun stringSwitch(s: String) : Int { + when(s) { + "ABCDEFG1" -> return 1 + "ABCDEFG2" -> return 2 + "ABCDEFG2" -> return 3 + "ABCDEFG3" -> return 4 + "ABCDEFG4" -> return 5 + "ABCDEFG5" -> return 6 + "ABCDEFG6" -> return 7 + "ABCDEFG7" -> return 8 + "ABCDEFG8" -> return 9 + "ABCDEFG9" -> return 10 + "ABCDEFG10" -> return 11 + "ABCDEFG11" -> return 12 + "ABCDEFG12" -> return 1 + "ABCDEFG13" -> return 2 + "ABCDEFG14" -> return 3 + "ABCDEFG15" -> return 4 + "ABCDEFG16" -> return 5 + "ABCDEFG17" -> return 6 + "ABCDEFG18" -> return 7 + "ABCDEFG19" -> return 8 + "ABCDEFG20" -> return 9 + else -> return -1 + } + } + + lateinit var denseIntData: IntArray + lateinit var sparseIntData: IntArray + + fun setupInts() { + denseIntData = IntArray(BENCHMARK_SIZE) { Random.nextInt(25) - 1 } + sparseIntData= IntArray(BENCHMARK_SIZE) { SPARSE_SWITCH_CASES[Random.nextInt(20)] } + } + + //Benchmark + fun testSparseIntSwitch() { + for (i in sparseIntData) { + Blackhole.consume(sparseIntSwitch(i)) + } + } + + //Benchmark + fun testDenseIntSwitch() { + for (i in denseIntData) { + Blackhole.consume(denseIntSwitch(i)) + } + } + + //Benchmark + fun testConstSwitch() { + for (i in denseIntData) { + Blackhole.consume(constSwitch(i)) + } + } + + //Benchmark + fun testObjConstSwitch() { + for (i in denseIntData) { + Blackhole.consume(objConstSwitch(i)) + } + } + + //Benchmark + fun testVarSwitch() { + for (i in denseIntData) { + Blackhole.consume(varSwitch(i)) + } + } + + var data : Array = arrayOf() + + fun setupStrings() { + data = Array(BENCHMARK_SIZE) { + "ABCDEFG" + Random.nextInt(22) + } + } + + //Benchmark + fun testStringsSwitch() { + val n = data.size + for (s in data) { + Blackhole.consume(stringSwitch(s)) + } + } + + enum class MyEnum { + ITEM1, ITEM2, ITEM3, ITEM4, ITEM5, ITEM6, ITEM7, ITEM8, ITEM9, ITEM10, ITEM11, ITEM12, ITEM13, ITEM14, ITEM15, ITEM16, ITEM17, ITEM18, ITEM19, ITEM20, ITEM21, ITEM22, ITEM23, ITEM24, ITEM25, ITEM26, ITEM27, ITEM28, ITEM29, ITEM30, ITEM31, ITEM32, ITEM33, ITEM34, ITEM35, ITEM36, ITEM37, ITEM38, ITEM39, ITEM40, ITEM41, ITEM42, ITEM43, ITEM44, ITEM45, ITEM46, ITEM47, ITEM48, ITEM49, ITEM50, ITEM51, ITEM52, ITEM53, ITEM54, ITEM55, ITEM56, ITEM57, ITEM58, ITEM59, ITEM60, ITEM61, ITEM62, ITEM63, ITEM64, ITEM65, ITEM66, ITEM67, ITEM68, ITEM69, ITEM70, ITEM71, ITEM72, ITEM73, ITEM74, ITEM75, ITEM76, ITEM77, ITEM78, ITEM79, ITEM80, ITEM81, ITEM82, ITEM83, ITEM84, ITEM85, ITEM86, ITEM87, ITEM88, ITEM89, ITEM90, ITEM91, ITEM92, ITEM93, ITEM94, ITEM95, ITEM96, ITEM97, ITEM98, ITEM99, ITEM100 + } + + private fun enumSwitch(x: MyEnum) : Int { + when (x) { + MyEnum.ITEM5 -> return 1 + MyEnum.ITEM10 -> return 2 + MyEnum.ITEM15 -> return 3 + MyEnum.ITEM20 -> return 4 + MyEnum.ITEM25 -> return 5 + MyEnum.ITEM30 -> return 6 + MyEnum.ITEM35 -> return 7 + MyEnum.ITEM40 -> return 8 + MyEnum.ITEM45 -> return 9 + MyEnum.ITEM50 -> return 10 + MyEnum.ITEM55 -> return 11 + MyEnum.ITEM60 -> return 12 + MyEnum.ITEM65 -> return 13 + MyEnum.ITEM70 -> return 14 + MyEnum.ITEM75 -> return 15 + MyEnum.ITEM80 -> return 16 + MyEnum.ITEM85 -> return 17 + MyEnum.ITEM90 -> return 18 + MyEnum.ITEM95 -> return 19 + MyEnum.ITEM100 -> return 20 + else -> return -1 + } + } + + private fun denseEnumSwitch(x: MyEnum) : Int { + when (x) { + MyEnum.ITEM1 -> return 1 + MyEnum.ITEM2 -> return 2 + MyEnum.ITEM3 -> return 3 + MyEnum.ITEM4 -> return 4 + MyEnum.ITEM5 -> return 5 + MyEnum.ITEM6 -> return 6 + MyEnum.ITEM7 -> return 7 + MyEnum.ITEM8 -> return 8 + MyEnum.ITEM9 -> return 9 + MyEnum.ITEM10 -> return 10 + MyEnum.ITEM11 -> return 11 + MyEnum.ITEM12 -> return 12 + MyEnum.ITEM13 -> return 13 + MyEnum.ITEM14 -> return 14 + MyEnum.ITEM15 -> return 15 + MyEnum.ITEM16 -> return 16 + MyEnum.ITEM17 -> return 17 + MyEnum.ITEM18 -> return 18 + MyEnum.ITEM19 -> return 19 + MyEnum.ITEM20 -> return 20 + else -> return -1 + } + } + + lateinit var enumData : Array + lateinit var denseEnumData : Array + + fun setupEnums() { + enumData = Array(BENCHMARK_SIZE) { + MyEnum.values()[it % MyEnum.values().size] + } + denseEnumData = Array(BENCHMARK_SIZE) { + MyEnum.values()[it % 20] + } + } + + //Benchmark + fun testEnumsSwitch() { + val n = enumData.size -1 + val data = enumData + for (i in 0..n) { + Blackhole.consume(enumSwitch(data[i])) + } + } + + //Benchmark + fun testDenseEnumsSwitch() { + val n = denseEnumData.size -1 + val data = denseEnumData + for (i in 0..n) { + Blackhole.consume(denseEnumSwitch(data[i])) + } + } + + sealed class MySealedClass { + class MySealedClass1: MySealedClass() + class MySealedClass2: MySealedClass() + class MySealedClass3: MySealedClass() + class MySealedClass4: MySealedClass() + class MySealedClass5: MySealedClass() + class MySealedClass6: MySealedClass() + class MySealedClass7: MySealedClass() + class MySealedClass8: MySealedClass() + class MySealedClass9: MySealedClass() + class MySealedClass10: MySealedClass() + } + + lateinit var sealedClassData: Array + + fun setupSealedClassses() { + sealedClassData = Array(BENCHMARK_SIZE) { + when(Random.nextInt(10)) { + 0 -> MySealedClass.MySealedClass1() + 1 -> MySealedClass.MySealedClass2() + 2 -> MySealedClass.MySealedClass3() + 3 -> MySealedClass.MySealedClass4() + 4 -> MySealedClass.MySealedClass5() + 5 -> MySealedClass.MySealedClass6() + 6 -> MySealedClass.MySealedClass7() + 7 -> MySealedClass.MySealedClass8() + 8 -> MySealedClass.MySealedClass9() + 9 -> MySealedClass.MySealedClass10() + else -> throw IllegalStateException() + } + } + } + + private fun sealedWhenSwitch(x: MySealedClass) : Int = + when (x) { + is MySealedClass.MySealedClass1 -> 1 + is MySealedClass.MySealedClass2 -> 2 + is MySealedClass.MySealedClass3 -> 3 + is MySealedClass.MySealedClass4 -> 4 + is MySealedClass.MySealedClass5 -> 5 + is MySealedClass.MySealedClass6 -> 6 + is MySealedClass.MySealedClass7 -> 7 + is MySealedClass.MySealedClass8 -> 8 + is MySealedClass.MySealedClass9 -> 9 + is MySealedClass.MySealedClass10 -> 10 + } + + + //Benchmark + fun testSealedWhenSwitch() { + val n = sealedClassData.size -1 + for (i in 0..n) { + Blackhole.consume(sealedWhenSwitch(sealedClassData[i])) + } + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/Utils.kt b/performance/src/main/kotlin/org/jetbrains/ring/Utils.kt new file mode 100644 index 00000000000..f3a24544ab6 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/Utils.kt @@ -0,0 +1,32 @@ +package org.jetbrains.ring + +import kotlin.system.measureNanoTime + +//-----------------------------------------------------------------------------// + +class Blackhole { + companion object { + var consumer = 0 + fun consume(value: Any) { + consumer += value.hashCode() + } + } +} + +//-----------------------------------------------------------------------------// + +class Random() { + companion object { + var seedInt = 0 + fun nextInt(boundary: Int = 100): Int { + seedInt = (3 * seedInt + 11) % boundary + return seedInt + } + + var seedDouble: Double = 0.1 + fun nextDouble(boundary: Double = 100.0): Double { + seedDouble = (7.0 * seedDouble + 7.0) % boundary + return seedDouble + } + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/WithIndiciesBenchmark.kt b/performance/src/main/kotlin/org/jetbrains/ring/WithIndiciesBenchmark.kt new file mode 100644 index 00000000000..04b38f4c27e --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/WithIndiciesBenchmark.kt @@ -0,0 +1,36 @@ +package org.jetbrains.ring + +open class WithIndiciesBenchmark { + private var _data: ArrayList? = null + val data: ArrayList + get() = _data!! + + fun setup() { + val list = ArrayList(BENCHMARK_SIZE) + for (n in classValues(BENCHMARK_SIZE)) + list.add(n) + _data = list + } + + //Benchmark + fun withIndicies() { + for ((index, value) in data.withIndex()) { + if (filterLoad(value)) { + Blackhole.consume(index) + Blackhole.consume(value) + } + } + } + + //Benchmark + fun withIndiciesManual() { + var index = 0 + for (value in data) { + if (filterLoad(value)) { + Blackhole.consume(index) + Blackhole.consume(value) + } + index++ + } + } +} diff --git a/performance/src/main/kotlin/org/jetbrains/ring/launcher.kt b/performance/src/main/kotlin/org/jetbrains/ring/launcher.kt new file mode 100644 index 00000000000..f33cfdf4903 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/launcher.kt @@ -0,0 +1,425 @@ +package org.jetbrains.ring + +import kotlin.system.measureNanoTime + +val BENCHMARK_SIZE = 100 + +//-----------------------------------------------------------------------------// + +class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) { + val results = mutableListOf() + + fun launch(benchmark: () -> Any?) { + var i = numWarmIterations + var j = numMeasureIterations + + while (i-- > 0) benchmark() + val time = measureNanoTime { + while (j-- > 0) benchmark() + } + results.add(time) + printResult(benchmark.toString(), time) + } + + //-------------------------------------------------------------------------// + + fun printResult(name: String, time: Long) { + val niceName = name.replace(" (Kotlin reflection is not available)", "").padEnd(45, ' ') + val niceTime = time.toString().padStart(10, ' ') + println(" $niceName : $niceTime") + } + + //-------------------------------------------------------------------------// + + fun runBenchmarks(): Long { + runAbstractMethodBenchmark() + runClassArrayBenchmark() + runClassBaselineBenchmark() + runClassListBenchmark() + runClassStreamBenchmark() + runCompanionObjectBenchmark() + runDefaultArgumentBenchmark() + runElvisBenchmark() + runEulerBenchmark() + runFibonacciBenchmark() + runInlineBenchmark() + runIntArrayBenchmark() + runIntBaselineBenchmark() + runIntListBenchmark() + runIntStreamBenchmark() + runLambdaBenchmark() + runLoopBenchmark() + runMatrixMapBenchmark() + runParameterNotNullAssertionBenchmark() + runPrimeListBenchmark() + runStringBenchmark() + runSwitchBenchmark() + runWithIndiciesBenchmark() + + return average() + } + + + //-------------------------------------------------------------------------// + + fun average(): Long { + val total = results.fold(0L) { total, next -> total + next } + return total / results.size + } + + //-------------------------------------------------------------------------// + + fun runAbstractMethodBenchmark() { + println("\nAbstractMethodBenchmark") + val benchmark = AbstractMethodBenchmark() + + launch(benchmark::sortStrings) + launch(benchmark::sortStringsWithComparator) + } + + //-------------------------------------------------------------------------// + + fun runClassArrayBenchmark() { + println("\nClassArrayBenchmark") + val benchmark = ClassArrayBenchmark() + benchmark.setup() + + launch(benchmark::copy) + launch(benchmark::copyManual) + launch(benchmark::filterAndCount) + launch(benchmark::filterAndMap) + launch(benchmark::filterAndMapManual) + launch(benchmark::filter) + launch(benchmark::filterManual) + launch(benchmark::countFilteredManual) + launch(benchmark::countFiltered) + launch(benchmark::countFilteredLocal) + } + + //-------------------------------------------------------------------------// + + fun runClassBaselineBenchmark() { + println("\nClassBaselineBenchmark") + val benchmark = ClassBaselineBenchmark() + + launch(benchmark::consume) + launch(benchmark::consumeField) + launch(benchmark::allocateList) + launch(benchmark::allocateArray) + launch(benchmark::allocateListAndFill) + launch(benchmark::allocateListAndWrite) + launch(benchmark::allocateArrayAndFill) + } + + //-------------------------------------------------------------------------// + + fun runClassListBenchmark() { + println("\nClassListBenchmark") + val benchmark = ClassListBenchmark() + benchmark.setup() + + launch(benchmark::copy) + launch(benchmark::copyManual) + launch(benchmark::filterAndCount) + launch(benchmark::filterAndCountWithLambda) + launch(benchmark::filterWithLambda) + launch(benchmark::mapWithLambda) + launch(benchmark::countWithLambda) + launch(benchmark::filterAndMapWithLambda) + launch(benchmark::filterAndMapWithLambdaAsSequence) + launch(benchmark::filterAndMap) + launch(benchmark::filterAndMapManual) + launch(benchmark::filter) + launch(benchmark::filterManual) + launch(benchmark::countFilteredManual) + launch(benchmark::countFiltered) + launch(benchmark::reduce) + } + + //-------------------------------------------------------------------------// + + fun runClassStreamBenchmark() { + println("\nClassStreamBenchmark") + val benchmark = ClassStreamBenchmark() + benchmark.setup() + + launch(benchmark::copy) + launch(benchmark::copyManual) + launch(benchmark::filterAndCount) + launch(benchmark::filterAndMap) + launch(benchmark::filterAndMapManual) + launch(benchmark::filter) + launch(benchmark::filterManual) + launch(benchmark::countFilteredManual) + launch(benchmark::countFiltered) + launch(benchmark::reduce) + } + + //-------------------------------------------------------------------------// + + fun runCompanionObjectBenchmark() { + println("\nCompanionObjectBenchmark") + val benchmark = CompanionObjectBenchmark() + + launch(benchmark::invokeRegularFunction) + launch(benchmark::invokeJvmStaticFunction) + } + + //-------------------------------------------------------------------------// + + fun runDefaultArgumentBenchmark() { + println("\nDefaultArgumentBenchmark") + val benchmark = DefaultArgumentBenchmark() + benchmark.setup() + + launch(benchmark::testOneOfTwo) + launch(benchmark::testTwoOfTwo) + launch(benchmark::testOneOfFour) + launch(benchmark::testFourOfFour) + launch(benchmark::testOneOfEight) + launch(benchmark::testEightOfEight) + } + + //-------------------------------------------------------------------------// + + fun runElvisBenchmark() { + println("\nElvisBenchmark") + val benchmark = ElvisBenchmark() + benchmark.setup() + + launch(benchmark::testElvis) + } + + //-------------------------------------------------------------------------// + + fun runEulerBenchmark() { + println("\nEulerBenchmark") + val benchmark = EulerBenchmark() + + launch(benchmark::problem1bySequence) + launch(benchmark::problem1) + launch(benchmark::problem2) + launch(benchmark::problem4) + launch(benchmark::problem8) + launch(benchmark::problem9) + launch(benchmark::problem14) + launch(benchmark::problem14full) + } + + + //-------------------------------------------------------------------------// + + fun runFibonacciBenchmark() { + println("\nFibonacciBenchmark") + val benchmark = FibonacciBenchmark() + launch(benchmark::calcClassic) + launch(benchmark::calc) + launch(benchmark::calcWithProgression) + launch(benchmark::calcSquare) + } + + //-------------------------------------------------------------------------// + + fun runInlineBenchmark() { + println("\nInlineBenchmark") + val benchmark = InlineBenchmark() + launch(benchmark::calculate) + launch(benchmark::calculateInline) + launch(benchmark::calculateGeneric) + launch(benchmark::calculateGenericInline) + } + + //-------------------------------------------------------------------------// + + fun runIntArrayBenchmark() { + println("\nIntArrayBenchmark") + val benchmark = IntArrayBenchmark() + benchmark.setup() + + launch(benchmark::copy) + launch(benchmark::copyManual) + launch(benchmark::filterAndCount) + launch(benchmark::filterSomeAndCount) + launch(benchmark::filterAndMap) + launch(benchmark::filterAndMapManual) + launch(benchmark::filter) + launch(benchmark::filterSome) + launch(benchmark::filterPrime) + launch(benchmark::filterManual) + launch(benchmark::filterSomeManual) + launch(benchmark::countFilteredManual) + launch(benchmark::countFilteredSomeManual) + launch(benchmark::countFilteredPrimeManual) + launch(benchmark::countFiltered) + launch(benchmark::countFilteredSome) + launch(benchmark::countFilteredPrime) + launch(benchmark::countFilteredLocal) + launch(benchmark::countFilteredSomeLocal) + launch(benchmark::reduce) + } + + //-------------------------------------------------------------------------// + + fun runIntBaselineBenchmark() { + println("\nIntBaselineBenchmark") + val benchmark = IntBaselineBenchmark() + + launch(benchmark::consume) + launch(benchmark::allocateList) + launch(benchmark::allocateArray) + launch(benchmark::allocateListAndFill) + launch(benchmark::allocateArrayAndFill) + } + + //-------------------------------------------------------------------------// + + fun runIntListBenchmark() { + println("\nIntListBenchmark") + val benchmark = IntListBenchmark() + benchmark.setup() + + launch(benchmark::copy) + launch(benchmark::copyManual) + launch(benchmark::filterAndCount) + launch(benchmark::filterAndMap) + launch(benchmark::filterAndMapManual) + launch(benchmark::filter) + launch(benchmark::filterManual) + launch(benchmark::countFilteredManual) + launch(benchmark::countFiltered) + launch(benchmark::countFilteredLocal) + launch(benchmark::reduce) + } + + //-------------------------------------------------------------------------// + + fun runIntStreamBenchmark() { + println("\nIntStreamBenchmark") + val benchmark = IntStreamBenchmark() + benchmark.setup() + + launch(benchmark::copy) + launch(benchmark::copyManual) + launch(benchmark::filterAndCount) + launch(benchmark::filterAndMap) + launch(benchmark::filterAndMapManual) + launch(benchmark::filter) + launch(benchmark::filterManual) + launch(benchmark::countFilteredManual) + launch(benchmark::countFiltered) + launch(benchmark::countFilteredLocal) + launch(benchmark::reduce) + } + + //-------------------------------------------------------------------------// + + fun runLambdaBenchmark() { + println("\nLambdaBenchmark") + val benchmark = LambdaBenchmark() + benchmark.setup() + + launch(benchmark::noncapturingLambda) + launch(benchmark::noncapturingLambdaNoInline) + launch(benchmark::capturingLambda) + launch(benchmark::capturingLambdaNoInline) + launch(benchmark::mutatingLambda) + launch(benchmark::mutatingLambdaNoInline) + launch(benchmark::methodReference) + launch(benchmark::methodReferenceNoInline) + } + + //-------------------------------------------------------------------------// + + fun runLoopBenchmark() { + println("\nLoopBenchmark") + val benchmark = LoopBenchmark() + benchmark.setup() + + launch(benchmark::arrayLoop) + launch(benchmark::arrayIndexLoop) + launch(benchmark::rangeLoop) + launch(benchmark::arrayListLoop) + launch(benchmark::arrayWhileLoop) + launch(benchmark::arrayForeachLoop) + launch(benchmark::arrayListForeachLoop) + } + + //-------------------------------------------------------------------------// + + fun runMatrixMapBenchmark() { + println("\nMatrixMapBenchmark") + val benchmark = MatrixMapBenchmark() + + launch(benchmark::add) + } + + //-------------------------------------------------------------------------// + + fun runParameterNotNullAssertionBenchmark() { + println("\nParameterNotNullAssertionBenchmark") + val benchmark = ParameterNotNullAssertionBenchmark() + + launch(benchmark::invokeOneArgWithNullCheck) + launch(benchmark::invokeOneArgWithoutNullCheck) + launch(benchmark::invokeTwoArgsWithNullCheck) + launch(benchmark::invokeTwoArgsWithoutNullCheck) + launch(benchmark::invokeEightArgsWithNullCheck) + launch(benchmark::invokeEightArgsWithoutNullCheck) + } + + //-------------------------------------------------------------------------// + + fun runPrimeListBenchmark() { + println("\nPrimeListBenchmark") + val benchmark = PrimeListBenchmark() + + launch(benchmark::calcDirect) + launch(benchmark::calcEratosthenes) + } + + //-------------------------------------------------------------------------// + + fun runStringBenchmark() { + println("\nStringBenchmark") + val benchmark = StringBenchmark() + benchmark.setup() + + launch(benchmark::stringConcat) + launch(benchmark::stringConcatNullable) + launch(benchmark::stringBuilderConcat) + launch(benchmark::stringBuilderConcatNullable) + launch(benchmark::summarizeSplittedCsv) + } + + //-------------------------------------------------------------------------// + + fun runSwitchBenchmark() { + println("\nSwitchBenchmark") + val benchmark = SwitchBenchmark() + benchmark.setupInts() + benchmark.setupStrings() + benchmark.setupEnums() + benchmark.setupSealedClassses() + + launch(benchmark::testSparseIntSwitch) + launch(benchmark::testDenseIntSwitch) + launch(benchmark::testConstSwitch) + launch(benchmark::testObjConstSwitch) + launch(benchmark::testVarSwitch) + launch(benchmark::testStringsSwitch) + launch(benchmark::testEnumsSwitch) + launch(benchmark::testDenseEnumsSwitch) + launch(benchmark::testSealedWhenSwitch) + } + + //-------------------------------------------------------------------------// + + fun runWithIndiciesBenchmark() { + println("\nWithIndiciesBenchmark") + val benchmark = WithIndiciesBenchmark() + benchmark.setup() + + launch(benchmark::withIndicies) + launch(benchmark::withIndiciesManual) + } +} \ No newline at end of file diff --git a/performance/src/main/kotlin/org/jetbrains/ring/zdf-win.kt b/performance/src/main/kotlin/org/jetbrains/ring/zdf-win.kt new file mode 100644 index 00000000000..b388dd67e90 --- /dev/null +++ b/performance/src/main/kotlin/org/jetbrains/ring/zdf-win.kt @@ -0,0 +1,504 @@ +package org.jetbrains.ring + +val zdf_win = listOf( +"-де", +"-ка", +"-либо", +"-нибудь", +"-с", +"-таки", +"-то", +"а", +"а-конто", +"а-ля", +"аба", +"абажур", +"абажурный", +"абаз", +"абазин", +"абазинец", +"абазинка", +"абазинский", +"абак", +"абака", +"аббат", +"аббатиса", +"аббатский", +"аббатство", +"аббревиатура", +"аббревиатурный", +"аббревиация", +"абдикация", +"абдомен", +"абдоминальный", +"абдуктор", +"абдукторный", +"абдукция", +"абелит", +"аберрационный", +"аберрация", +"абзац", +"абзацный", +"абиетин", +"абиетиновый", +"абиссальный", +"абиссинец", +"абиссинский", +"абитуриент", +"абитуриентка", +"абитуриентский", +"аблактировать", +"аблактировка", +"аблятив", +"абляут", +"абляция", +"аболиционизм", +"аболиционист", +"аболиционистский", +"аболиция", +"абонемент", +"абонементный", +"абонент", +"абонентка", +"абонентный", +"абонентский", +"абонирование", +"абонировать", +"абонироваться", +"абордаж", +"абордажный", +"абордировать", +"абориген", +"аборигенный", +"аборт", +"абортарий", +"абортивный", +"абортировать", +"абразив", +"абразивный", +"абразионный", +"абразия", +"абракадабра", +"абреже", +"абрек", +"абрикос", +"абрикосный", +"абрикосовка", +"абрикосовый", +"абрикотин", +"абрис", +"абрисный", +"абсент", +"абсентеизм", +"абсентеист", +"абсолют", +"абсолютивный", +"абсолютизирование", +"абсолютизировать", +"абсолютизм", +"абсолютист", +"абсолютистский", +"абсолютность", +"абсолютный", +"абсолюция", +"абсорбент", +"абсорбер", +"абсорбировать", +"абсорбционный", +"абсорбция", +"абстинент", +"абстрагирование", +"абстрагировать", +"абстрагироваться", +"абстракт", +"абстрактность", +"абстрактный", +"абстракционизм", +"абстракционист", +"абстракционистский", +"абстракция", +"абсурд", +"абсурдность", +"абсурдный", +"абсцесс", +"абсцисса", +"абулия", +"абхаз", +"абхазец", +"абхазка", +"абхазский", +"абцуг", +"абштрих", +"абъюрация", +"абы", +"авалист", +"аваль", +"авангард", +"авангардизм", +"авангардист", +"авангардистский", +"авангардный", +"аванзал", +"аванзальный", +"аванкамера", +"аванложа", +"аванпорт", +"аванпост", +"аванпостный", +"аванс", +"авансирование", +"авансировать", +"авансовый", +"авансом", +"авансцена", +"авантаж", +"авантажный", +"авантюра", +"авантюризм", +"авантюрин", +"авантюриновый", +"авантюрист", +"авантюристический", +"авантюристичный", +"авантюристка", +"авантюристский", +"авантюрность", +"авантюрный", +"авар", +"аварец", +"аварийность", +"аварийный", +"аварийщик", +"авария", +"аварка", +"аварский", +"авгиев", +"авгит", +"авгур", +"август", +"августейший", +"августинец", +"августовский", +"авдотка", +"авеню", +"аверс", +"авестийский", +"авиабаза", +"авиабензин", +"авиагоризонт", +"авиадвигатель", +"авиадесант", +"авиадесантный", +"авиазавод", +"авиаконструктор", +"авиалиния", +"авиаматка", +"авиамоделизм", +"авиамоделист", +"авиамодель", +"авиамодельный", +"авиамотор", +"авиамоторный", +"авианосец", +"авиапочта", +"авиаприбор", +"авиапромышленность", +"авиапромышленный", +"авиаразведка", +"авиастроение", +"авиастроитель", +"авиастроительный", +"авиастроительство", +"авиасъёмка", +"авиатехник", +"авиатор", +"авиаторский", +"авиатранспорт", +"авиатранспортный", +"авиатрасса", +"авиационный", +"авиация", +"авиачасть", +"авиашкола", +"авиетка", +"авизировать", +"авизный", +"авизо", +"авитаминоз", +"авитаминозный", +"авифауна", +"авокадо", +"авось", +"авоська", +"аврал", +"авралить", +"авральный", +"авран", +"аврора", +"австралиец", +"австралийка", +"австралийский", +"австралопитек", +"австриец", +"австрийка", +"австрийский", +"австрияк", +"австриячка", +"австро-венгерский", +"автаркический", +"автаркия", +"авто", +"автобаза", +"автобиографический", +"автобиографичность", +"автобиографичный", +"автобиография", +"автоблокировка", +"автоблокировочный", +"автобус", +"автобусник", +"автобусный", +"автовакцина", +"автовесы", +"автовокзал", +"автогамия", +"автоген", +"автогенез", +"автогенератор", +"автогенный", +"автогенщик", +"автогипноз", +"автогонки", +"автогравюра", +"автограф", +"автографический", +"автография", +"автогужевой", +"автодидакт", +"автодоение", +"автодорожник", +"автодорожный", +"автодрезина", +"автодром", +"автожир", +"автозавод", +"автозаводец", +"автозаводский", +"автозаводской", +"автозаправочный", +"автозаправщик", +"автоинспектор", +"автоинспекция", +"автокар", +"автокара", +"автокатализ", +"автокефалия", +"автокефальный", +"автоклав", +"автоклуб", +"автоколонна", +"автокомбинат", +"автокран", +"автократ", +"автократический", +"автократия", +"автокружок", +"автол", +"автолавка", +"автолиз", +"автолитография", +"автолюбитель", +"автолюбительство", +"автомагистраль", +"автомат", +"автоматизация", +"автоматизирование", +"автоматизировать", +"автоматизироваться", +"автоматизм", +"автоматика", +"автоматический", +"автоматичность", +"автоматичный", +"автоматный", +"автоматчик", +"автоматчица", +"автомашина", +"автомашинист", +"автомеханик", +"автомобилестроение", +"автомобилестроитель", +"автомобилестроительный", +"автомобилизация", +"автомобилизм", +"автомобилист", +"автомобилистка", +"автомобиль", +"автомобильный", +"автомобильчик", +"автоморфизм", +"автомотоклуб", +"автомоторный", +"автомотошкола", +"автомотриса", +"автономист", +"автономистский", +"автономический", +"автономия", +"автономность", +"автономный", +"автопарк", +"автоперевозка", +"автопилот", +"автопластика", +"автоплуг", +"автопогрузчик", +"автоподъёмник", +"автопоезд", +"автопоилка", +"автопокрышка", +"автопортрет", +"автопробег", +"автопромышленность", +"автор", +"авторалли", +"авторегулятор", +"авторемонтник", +"авторемонтный", +"автореферат", +"авторефрижератор", +"авторизация", +"авторизованный", +"авторизовать", +"авторитарность", +"авторитарный", +"авторитет", +"авторитетность", +"авторитетный", +"авторота", +"авторские", +"авторский", +"авторство", +"авторулевой", +"авторучка", +"автосани", +"автосборка", +"автосварщик", +"автоспорт", +"автостанция", +"автостоп", +"автострада", +"автостроение", +"автостроитель", +"автосцепка", +"автотележка", +"автотип", +"автотипический", +"автотипия", +"автотипный", +"автотомия", +"автотормоз", +"автотормозной", +"автотракторный", +"автотранспорт", +"автотранспортный", +"автотрансформатор", +"автотрасса", +"автотуризм", +"автотурист", +"автоукладчик", +"автофургон", +"автохозяйство", +"автохром", +"автохромный", +"автохтон", +"автохтонный", +"автоцистерна", +"авточасть", +"автошкола", +"автоштурман", +"авуары", +"ага", +"ага-хан", +"агава", +"агалит", +"агальматолит", +"агама", +"агами", +"агамия", +"агамогония", +"агар-агар", +"агарный", +"агаровый", +"агарянин", +"агат", +"агатный", +"агатовый", +"агглютинативность", +"агглютинативный", +"агглютинация", +"агглютинин", +"агглютинирующий", +"аггравация", +"агент", +"агентский", +"агентство", +"агентура", +"агентурный", +"агиографический", +"агиография", +"агиология", +"агитатор", +"агитаторский", +"агитаторша", +"агитационный", +"агитация", +"агитбригада", +"агитировать", +"агитка", +"агиткампания", +"агитмассовый", +"агитпоезд", +"агитпроп", +"агитпункт", +"аглицкий", +"агломерат", +"агломератчик", +"агломерационный", +"агломерация", +"агломерировать", +"агломерироваться", +"агнат", +"агнец", +"агнозия", +"агностик", +"агностицизм", +"агностический", +"агонизировать", +"агонический", +"агония", +"агорафобия", +"аграмант", +"аграмантовый", +"аграрий", +"аграрник", +"аграрный", +"аграф", +"аграфия", +"агрегат", +"агрегатный", +"агреман", +"агрессивность", +"агрессивный", +"агрессия", +"агрессор", +"агрикультура", +"агрикультурный", +"агробаза", +"агробиолог", +"агробиологический", +"агробиология", +"агроботаника", +"агрозоотехника", +"агромелиорация" +) diff --git a/settings.gradle b/settings.gradle index 2433157663a..d4599e419c1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -28,3 +28,4 @@ include ':shared' include ':tools:helpers' include ':tools:kotlin-native-gradle-plugin' include ':utilities' +include ':performance' \ No newline at end of file