はじめに
Javaパフォーマンスの本を読んでいて、JavaのBoolean型は個々に実体を生成するのでHeapを余計に食う、と書いてあったので、どういう書き方をするのが良いのか調べてみた。ついでにScalaがどうなってるのかも調べた。
Java
System.identityHashCode
は参照の比較に使える。同じ値であれば「ほぼ」同じものを参照している(厳密には被る可能性がある)
Main.java
public class Main
{
public static void main(String[] arg) {
Boolean a = Boolean.TRUE;
Boolean b = Boolean.TRUE;
Boolean c = true;
Boolean d = true;
Boolean e = new Boolean(true);
Boolean f = new Boolean(true);
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(System.identityHashCode(c));
System.out.println(System.identityHashCode(d));
System.out.println(System.identityHashCode(e));
System.out.println(System.identityHashCode(f));
}
}
Javaパフォーマンスで推奨されているのは、Boolean.TRUEで代入せよ、というものであるが、少なくともJava8では直接リテラルを代入しても同じ効果が得られる。newすると勿論別のinstanceが生成される(newでは必ず新しい実体を生成する必要がある)
Scala
Main.scala
object Main extends App {
val a = true
val b = true
// val c = new Boolean(true) // CompileError!
println(System.identityHashCode(a))
println(System.identityHashCode(b))
}
ScalaはそもそもBooleanはprimitiveだしnewできないようになっていて更にヒープを食いにくい構造。
まとめ
- newは必要が無い場合でも新しい実体を生成してHeapを食うので極力避けよう
- Boolean.TRUEを敢えて使う必要性を感じない。使ってもいい。
- Scalaは何も考えずとも良きに計らってくれる。Scala使おう