OctoTest benchmark inserted in testsuite
This commit is contained in:
committed by
KonstantinAnisimov
parent
99dd7227dc
commit
f2921b0dcc
@@ -9,5 +9,8 @@ fun main(args: Array<String>) {
|
||||
numMeasureIterations = args[1].toInt()
|
||||
}
|
||||
|
||||
println("Ring starting")
|
||||
println(" warmup iterations count: $numWarmIterations")
|
||||
println(" measure iterations count: $numMeasureIterations")
|
||||
Launcher(numWarmIterations, numMeasureIterations).runBenchmarks()
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Created by semoro on 07.07.17.
|
||||
*/
|
||||
fun octoTest() {
|
||||
val tree = OctoTree<Boolean>(4)
|
||||
val to = (2 shl tree.depth)
|
||||
|
||||
var x = 0
|
||||
var y = 0
|
||||
var z = 0
|
||||
|
||||
while (x < to) {
|
||||
y = 0
|
||||
while (y < to) {
|
||||
z = 0
|
||||
while (z < to) {
|
||||
val c = (z + to * y + to * to * x) % 2 == 0
|
||||
|
||||
tree.set(x, y, z, c)
|
||||
z++
|
||||
}
|
||||
y++
|
||||
}
|
||||
x++
|
||||
}
|
||||
|
||||
x = 0
|
||||
y = 0
|
||||
z = 0
|
||||
while (x < to) {
|
||||
y = 0
|
||||
while (y < to) {
|
||||
z = 0
|
||||
while (z < to) {
|
||||
val c = (z + to * y + to * to * x) % 2 == 0
|
||||
|
||||
val res = tree.get(x, y, z)
|
||||
|
||||
assert(res == c)
|
||||
z++
|
||||
}
|
||||
y++
|
||||
}
|
||||
x++
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
|
||||
open class OctoTree<T>(val depth: Int) {
|
||||
|
||||
private var root: Node<T>? = null
|
||||
private var actual = false
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun get(x: Int, y: Int, z: Int): T? {
|
||||
var dep = depth
|
||||
var iter = root
|
||||
while (true) {
|
||||
if (iter == null) return null
|
||||
else if (iter is Node.Leaf) return iter.value
|
||||
|
||||
iter = (iter as Node.Branch<T>).nodes[number(x, y, z, --dep)]
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun set(x: Int, y: Int, z: Int, value: T) {
|
||||
if (root == null) root = Node.Branch()
|
||||
if (root!!.set(x, y, z, value, depth - 1)) {
|
||||
root = Node.Leaf(value)
|
||||
}
|
||||
actual = false
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun toString(): String = root.toString()
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
sealed class Node<T> {
|
||||
|
||||
abstract fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
class Leaf<T>(var value: T) : Node<T>() {
|
||||
|
||||
override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean {
|
||||
throw UnsupportedOperationException("set on Leaf element")
|
||||
}
|
||||
|
||||
override fun toString(): String = "L{$value}"
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
|
||||
class Branch<T>() : Node<T>() {
|
||||
|
||||
constructor(value: T, exclude: Int) : this() {
|
||||
|
||||
var i = 0
|
||||
while (i < 8) {
|
||||
if (i != exclude) {
|
||||
nodes[i] = Leaf(value)
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
private fun canClusterize(value: T): Boolean {
|
||||
var i = 0
|
||||
while (i < 8) {
|
||||
val w = nodes[i]
|
||||
if (w == null || w !is Leaf || value != w.value) {
|
||||
return false
|
||||
}
|
||||
i++
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun set(x: Int, y: Int, z: Int, value: T, depth: Int): Boolean {
|
||||
val branchIndex = number(x, y, z, depth)
|
||||
val node = nodes[branchIndex]
|
||||
when (node) {
|
||||
null -> {
|
||||
if (depth == 0) {
|
||||
nodes[branchIndex] = Leaf(value)
|
||||
return canClusterize(value)
|
||||
} else {
|
||||
nodes[branchIndex] = Branch()
|
||||
}
|
||||
}
|
||||
is Leaf<T> -> {
|
||||
if (node.value == value) {
|
||||
return false
|
||||
} else if (depth == 0) {
|
||||
node.value = value
|
||||
return canClusterize(value)
|
||||
}
|
||||
nodes[branchIndex] = Branch(node.value, number(x, y, z, depth - 1))
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes[branchIndex]!!.set(x, y, z, value, depth - 1)) {
|
||||
nodes[branchIndex] = Leaf(value)
|
||||
return canClusterize(value)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val nodes = arrayOfNulls<Node<T>>(8)
|
||||
override fun toString(): String = nodes.joinToString(prefix = "[", postfix = "]")
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
companion object {
|
||||
fun number(x: Int, y: Int, z: Int, depth: Int): Int {
|
||||
val mask = 1 shl depth
|
||||
if (x and mask != 0) {
|
||||
if (y and mask != 0) {
|
||||
if (z and mask != 0)
|
||||
return 7
|
||||
return 6
|
||||
}
|
||||
if (z and mask != 0)
|
||||
return 5
|
||||
return 4
|
||||
}
|
||||
if (y and mask != 0) {
|
||||
if (z and mask != 0)
|
||||
return 3
|
||||
return 2
|
||||
}
|
||||
if (z and mask != 0)
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.ring
|
||||
|
||||
import octoTest
|
||||
import kotlin.system.measureNanoTime
|
||||
|
||||
val BENCHMARK_SIZE = 100
|
||||
@@ -25,16 +26,18 @@ val BENCHMARK_SIZE = 100
|
||||
class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) {
|
||||
val results = mutableMapOf<String, Long>()
|
||||
|
||||
fun launch(benchmark: () -> Any?): Long {
|
||||
var i = numWarmIterations
|
||||
var j = numMeasureIterations
|
||||
fun launch(benchmark: () -> Any?, coeff: Double = 1.0): Long { // If benchmark runs too long - use coeff to speed it up.
|
||||
var i = (numWarmIterations * coeff).toInt()
|
||||
var j = (numMeasureIterations * coeff).toInt()
|
||||
|
||||
while (i-- > 0) benchmark()
|
||||
val time = measureNanoTime {
|
||||
while (j-- > 0) benchmark()
|
||||
while (j-- > 0) {
|
||||
benchmark()
|
||||
}
|
||||
}
|
||||
|
||||
return time / numMeasureIterations
|
||||
return (time / numMeasureIterations / coeff).toLong()
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -63,16 +66,29 @@ class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) {
|
||||
runStringBenchmark()
|
||||
runSwitchBenchmark()
|
||||
runWithIndiciesBenchmark()
|
||||
runOctoTest()
|
||||
|
||||
printResults()
|
||||
printResultsNormalized()
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun printResults() {
|
||||
fun printResultsAsTime() {
|
||||
results.forEach {
|
||||
val niceName = "\"${it.key}\"".padEnd(51)
|
||||
val niceTime = "${it.value}".padStart(10)
|
||||
println(" $niceName to ${niceTime}L,")
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun printResultsNormalized() {
|
||||
var total = 0.0
|
||||
results.forEach {
|
||||
val normaTime = NormaResults[it.key]
|
||||
if (normaTime == null) println("ERROR: no norma for benchmark ${it.key}")
|
||||
|
||||
val norma = it.value.toDouble() / normaTime!!.toDouble()
|
||||
val niceName = it.key.padEnd(50, ' ')
|
||||
val niceNorma = norma.toString(2).padStart(10, ' ')
|
||||
@@ -417,7 +433,13 @@ class Launcher(val numWarmIterations: Int, val numMeasureIterations: Int) {
|
||||
results["WithIndicies.withIndiciesManual"] = launch(benchmark::withIndiciesManual)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------//
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun runOctoTest() {
|
||||
results["OctoTest"] = launch(::octoTest, 0.1)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun Double.toString(n: Int): String {
|
||||
val str = this.toString()
|
||||
|
||||
@@ -173,5 +173,6 @@ val NormaResults = mapOf(
|
||||
"Switch.testDenseEnumsSwitch" to 208L,
|
||||
"Switch.testSealedWhenSwitch" to 172L,
|
||||
"WithIndicies.withIndicies" to 2303L,
|
||||
"WithIndicies.withIndiciesManual" to 2256L
|
||||
"WithIndicies.withIndiciesManual" to 2256L,
|
||||
"OctoTest" to 2515062L
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user