-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Looking at the cost of trait fowarders
Hypothesis is that the forwarders in subclasses impose a cost due to megamorphic virtual calls. // Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, mixed mode) > jmh:run -i 10 -wi 5 -f2 -t1 .*Mixin.* [info] Benchmark (count) Mode Cnt Score Error Units [info] MixinForwarderBenchmark.baseClass_1 16 thrpt 20 18537399.061 ± 521221.353 ops/s [info] MixinForwarderBenchmark.baseClass_16 16 thrpt 20 19137762.320 ± 510049.157 ops/s [info] MixinForwarderBenchmark.baseTrait_1 16 thrpt 20 18178697.687 ± 404180.617 ops/s [info] MixinForwarderBenchmark.baseTrait_16 16 thrpt 20 10786408.479 ± 162705.033 ops/s [info] MixinForwarderBenchmark.jbaseInterface_1 16 thrpt 20 18531993.312 ± 401611.669 ops/s [info] MixinForwarderBenchmark.jbaseInterface_16 16 thrpt 20 9642052.651 ± 228326.457 ops/s [success] Total time: 188 s, completed 22/04/2016 6:39:08 PM
- Loading branch information
Showing
2 changed files
with
163 additions
and
0 deletions.
There are no files selected for viewing
140 changes: 140 additions & 0 deletions
140
src/main/scala/scala/tools/nsc/MixinForwarderBenchmark.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package scala.tools.nsc | ||
|
||
import java.util.Random | ||
|
||
import org.openjdk.jmh.annotations._ | ||
import org.openjdk.jmh.infra.Blackhole | ||
|
||
import scala.annotation.meta.{field, getter} | ||
|
||
@State(Scope.Thread) | ||
class MixinForwarderBenchmark { | ||
class C { | ||
def foo = 42 | ||
} | ||
class C_1 extends C | ||
class C_2 extends C | ||
class C_3 extends C | ||
class C_4 extends C | ||
class C_5 extends C | ||
class C_6 extends C | ||
class C_7 extends C | ||
class C_8 extends C | ||
class C_9 extends C | ||
class C_10 extends C | ||
class C_11 extends C | ||
class C_12 extends C | ||
class C_13 extends C | ||
class C_14 extends C | ||
class C_15 extends C | ||
class C_16 extends C | ||
trait T { | ||
def foo = 42 | ||
} | ||
class T_1 extends T | ||
class T_2 extends T | ||
class T_3 extends T | ||
class T_4 extends T | ||
class T_5 extends T | ||
class T_6 extends T | ||
class T_7 extends T | ||
class T_8 extends T | ||
class T_9 extends T | ||
class T_10 extends T | ||
class T_11 extends T | ||
class T_12 extends T | ||
class T_13 extends T | ||
class T_14 extends T | ||
class T_15 extends T | ||
class T_16 extends T | ||
|
||
@(Param @field)(Array("16")) | ||
private[this] var count: Int = 0 | ||
|
||
private[this] var zero: Int = 0 | ||
|
||
private[this] val cs_16 = Array(new C_1, new C_2, new C_3, new C_4, new C_5, new C_6, new C_7, new C_8, new C_9, new C_10, new C_11, new C_12, new C_13, new C_14, new C_15, new C_16) | ||
private[this] val ts_16 = Array(new T_1, new T_2, new T_3, new T_4, new T_5, new T_6, new T_7, new T_8, new T_9, new T_10, new T_11, new T_12, new T_13, new T_14, new T_15, new T_16) | ||
import MixinForwarderBenchmarkSupport._ | ||
private[this] val js_16 = Array[J](new J_1, new J_2, new J_3, new J_4, new J_5, new J_6, new J_7, new J_8, new J_9, new J_10, new J_11, new J_12, new J_13, new J_14, new J_15, new J_16) | ||
|
||
private[this] var cs_16_random: Array[C] = _ | ||
private[this] var ts_16_random: Array[T] = _ | ||
private[this] var js_16_random: Array[J] = _ | ||
|
||
@Setup | ||
def create(): Unit = { | ||
val r = new Random() | ||
cs_16_random = Array.tabulate(count) { | ||
_ => cs_16.apply(r.nextInt(cs_16.length)) | ||
} | ||
|
||
ts_16_random = Array.tabulate(count) { | ||
_ => ts_16.apply(r.nextInt(ts_16.length)) | ||
} | ||
|
||
js_16_random = Array.tabulate(count) { | ||
_ => js_16.apply(r.nextInt(js_16.length)) | ||
} | ||
} | ||
|
||
@Benchmark | ||
def baseClass_1(bh: Blackhole): Unit = { | ||
var i = 0 | ||
val c = count | ||
while (i < c) { | ||
bh.consume(cs_16_random(zero)) | ||
i += 1 | ||
} | ||
} | ||
|
||
@Benchmark | ||
def baseClass_16(bh: Blackhole): Unit = { | ||
var i = 0 | ||
val c = count | ||
while (i < c) { | ||
bh.consume(cs_16_random(i).foo) | ||
i += 1 | ||
} | ||
} | ||
|
||
@Benchmark | ||
def baseTrait_1(bh: Blackhole): Unit = { | ||
var i = 0 | ||
val c = count | ||
while (i < c) { | ||
bh.consume(ts_16_random(zero).foo) | ||
i += 1 | ||
} | ||
} | ||
|
||
@Benchmark | ||
def baseTrait_16(bh: Blackhole): Unit = { | ||
var i = 0 | ||
val c = count | ||
while (i < c) { | ||
bh.consume(ts_16_random(i).foo) | ||
i += 1 | ||
} | ||
} | ||
|
||
@Benchmark | ||
def jbaseInterface_1(bh: Blackhole): Unit = { | ||
var i = 0 | ||
val c = count | ||
while (i < c) { | ||
bh.consume(js_16_random(zero).foo) | ||
i += 1 | ||
} | ||
} | ||
|
||
@Benchmark | ||
def jbaseInterface_16(bh: Blackhole): Unit = { | ||
var i = 0 | ||
val c = count | ||
while (i < c) { | ||
bh.consume(js_16_random(i).foo) | ||
i += 1 | ||
} | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/main/scala/scala/tools/nsc/MixinForwarderBenchmarkSupport.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package scala.tools.nsc; | ||
|
||
public class MixinForwarderBenchmarkSupport { | ||
interface J { | ||
default int foo() { return 42; } | ||
} | ||
public static class J_1 implements J {} | ||
public static class J_2 implements J {} | ||
public static class J_3 implements J {} | ||
public static class J_4 implements J {} | ||
public static class J_5 implements J {} | ||
public static class J_6 implements J {} | ||
public static class J_7 implements J {} | ||
public static class J_8 implements J {} | ||
public static class J_9 implements J {} | ||
public static class J_10 implements J {} | ||
public static class J_11 implements J {} | ||
public static class J_12 implements J {} | ||
public static class J_13 implements J {} | ||
public static class J_14 implements J {} | ||
public static class J_15 implements J {} | ||
public static class J_16 implements J {} | ||
} |
3b4594c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the scala code is compiled with 2.11.x?
3b4594c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep