From 6ceeebe73af16e551fc5bf1311167a54e7ed49a7 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Mon, 9 Sep 2019 13:29:13 +0300 Subject: [PATCH] Added benchmarks on interface casts & calls --- performance/ring/src/main/kotlin/main.kt | 4 +- .../org/jetbrains/ring/CallsBenchmark.kt | 36 ++++++++++ .../org/jetbrains/ring/CastsBenchmark.kt | 65 +++++++++++++++---- 3 files changed, 93 insertions(+), 12 deletions(-) diff --git a/performance/ring/src/main/kotlin/main.kt b/performance/ring/src/main/kotlin/main.kt index 0ba8a0448f1..440d3e5f51f 100644 --- a/performance/ring/src/main/kotlin/main.kt +++ b/performance/ring/src/main/kotlin/main.kt @@ -199,11 +199,13 @@ class RingLauncher : Launcher() { "Calls.interfaceMethodMonomorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_MonomorphicCallsite() }), "Calls.interfaceMethodBimorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_BimorphicCallsite() }), "Calls.interfaceMethodTrimorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_TrimorphicCallsite() }), + "Calls.interfaceMethodHexamorphic" to BenchmarkEntryWithInit.create(::CallsBenchmark, { interfaceMethodCall_HexamorphicCallsite() }), "Calls.returnBoxUnboxFolding" to BenchmarkEntryWithInit.create(::CallsBenchmark, { returnBoxUnboxFolding() }), "Calls.parameterBoxUnboxFolding" to BenchmarkEntryWithInit.create(::CallsBenchmark, { parameterBoxUnboxFolding() }), "CoordinatesSolver.solve" to BenchmarkEntryWithInit.create(::CoordinatesSolverBenchmark, { solve() }), "GraphSolver.solve" to BenchmarkEntryWithInit.create(::GraphSolverBenchmark, { solve() }), - "Casts.classCast" to BenchmarkEntryWithInit.create(::CastsBenchmark, { classCast() }) + "Casts.classCast" to BenchmarkEntryWithInit.create(::CastsBenchmark, { classCast() }), + "Casts.interfaceCast" to BenchmarkEntryWithInit.create(::CastsBenchmark, { interfaceCast() }) ) ) } diff --git a/performance/ring/src/main/kotlin/org/jetbrains/ring/CallsBenchmark.kt b/performance/ring/src/main/kotlin/org/jetbrains/ring/CallsBenchmark.kt index 1242094de42..92b7ee3b2cf 100644 --- a/performance/ring/src/main/kotlin/org/jetbrains/ring/CallsBenchmark.kt +++ b/performance/ring/src/main/kotlin/org/jetbrains/ring/CallsBenchmark.kt @@ -138,6 +138,18 @@ open class CallsBenchmark { override fun foo() = 314 } + open class X : A() { + override fun foo() = 456456 + } + + open class Y : A() { + override fun foo() = -398473 + } + + open class Z : A() { + override fun foo() = 78298734 + } + val d = D() val a1: A = B() val a2: A = C() @@ -145,6 +157,9 @@ open class CallsBenchmark { val i1: I = a1 val i2: I = a2 val i3: I = d + val i4: I = X() + val i5: I = Y() + val i6: I = Z() fun finalMethodCall(): Int { var x = 0 @@ -223,6 +238,27 @@ open class CallsBenchmark { return x } + fun interfaceMethodCall_HexamorphicCallsite(): Int { + var x = 0 + // TODO: optimize fields accesses + val i1 = i1 + val i2 = i2 + val i3 = i3 + val i4 = i4 + val i5 = i5 + val i6 = i6 + for (i in 0 until RUNS) + x += (when (i % 6) { + 1 -> i1 + 2 -> i2 + 3 -> i3 + 4 -> i4 + 5 -> i5 + else -> i6 + }).foo() + return x + } + abstract class E { abstract fun foo(): Any } diff --git a/performance/ring/src/main/kotlin/org/jetbrains/ring/CastsBenchmark.kt b/performance/ring/src/main/kotlin/org/jetbrains/ring/CastsBenchmark.kt index 8170cb23323..a9e6a4d2299 100644 --- a/performance/ring/src/main/kotlin/org/jetbrains/ring/CastsBenchmark.kt +++ b/performance/ring/src/main/kotlin/org/jetbrains/ring/CastsBenchmark.kt @@ -29,7 +29,7 @@ class CastsBenchmark { interface I8: I0, I1 open class C8: C3(), I8 - private fun foo(c: Any, x: Int, i: Int): Int { + private fun foo_class(c: Any, x: Int, i: Int): Int { var x = x if (c is C0) x += i if (c is C1) x = x xor i @@ -44,6 +44,21 @@ class CastsBenchmark { return x } + private fun foo_iface(c: Any, x: Int, i: Int): Int { + var x = x + if (c is I0) x += i + if (c is I1) x = x xor i + if (c is I2) x += i + if (c is I3) x = x xor i + if (c is I4) x += i + if (c is I5) x = x xor i + if (c is I6) x += i + if (c is I7) x = x xor i + if (c is I8) x += i + if (c is I9) x = x xor i + return x + } + fun classCast(): Int { val c0: Any = C0() val c1: Any = C1() @@ -58,16 +73,44 @@ class CastsBenchmark { var x = 0 for (i in 0 until RUNS) { - x = foo(c0, x, i) - x = foo(c1, x, i) - x = foo(c2, x, i) - x = foo(c3, x, i) - x = foo(c4, x, i) - x = foo(c5, x, i) - x = foo(c6, x, i) - x = foo(c7, x, i) - x = foo(c8, x, i) - x = foo(c9, x, i) + x += foo_class(c0, x, i) + x += foo_class(c1, x, i) + x += foo_class(c2, x, i) + x += foo_class(c3, x, i) + x += foo_class(c4, x, i) + x += foo_class(c5, x, i) + x += foo_class(c6, x, i) + x += foo_class(c7, x, i) + x += foo_class(c8, x, i) + x += foo_class(c9, x, i) + } + return x + } + + fun interfaceCast(): Int { + val c0: Any = C0() + val c1: Any = C1() + val c2: Any = C2() + val c3: Any = C3() + val c4: Any = C4() + val c5: Any = C5() + val c6: Any = C6() + val c7: Any = C7() + val c8: Any = C8() + val c9: Any = C9() + + var x = 0 + for (i in 0 until RUNS) { + x += foo_iface(c0, x, i) + x += foo_iface(c1, x, i) + x += foo_iface(c2, x, i) + x += foo_iface(c3, x, i) + x += foo_iface(c4, x, i) + x += foo_iface(c5, x, i) + x += foo_iface(c6, x, i) + x += foo_iface(c7, x, i) + x += foo_iface(c8, x, i) + x += foo_iface(c9, x, i) } return x }