Scalaの標準ライブラリにはLongMapやIntMapという、keyが特定の型に特化したMapがあります。
特化しているなら、それらの型の場合にはこれを使った方が効率いいのでは???と思うかもしれません。
しかし、先に結論を書いておくと、2025年時点のScalaにおいて、そんなことはない、という記事です。*1
速度は知りませんが、以下の方法ですごく雑に実験をしました
- Scala 2.13.17のREPLを起動
- REPL上で、以下のように、immutableなHashMapとLongMapを大量に生成
- もちろん、それぞれREPLは起動し直してします
- 他の条件は同じ
- メモリ解放されないようにあえてlazy valで保持したので、そこからさらに
System.gcなどしても大して変わらない- lazyなのは、単にREPLに表示させようとすると無駄に時間消費するだけなので、それ避けるため
- そのREPLのJVMプロセスを、このツール https://visualvm.github.io/ で観察
Welcome to Scala 2.13.17 (OpenJDK 64-Bit Server VM, Java 21.0.8). Type in expressions for evaluation. Or try :help. scala> lazy val x = List.tabulate(10000)(n => scala.collection.immutable.HashMap((1 to n).map(a => (a: Long) -> a): _*)) lazy val x: List[scala.collection.immutable.HashMap[Long,Int]] // unevaluated scala> println(x.size) 10000
Welcome to Scala 2.13.17 (OpenJDK 64-Bit Server VM, Java 21.0.8). Type in expressions for evaluation. Or try :help. scala> lazy val x = List.tabulate(10000)(n => scala.collection.immutable.LongMap((1 to n).map(a => (a: Long) -> a): _*)) lazy val x: List[scala.collection.immutable.LongMap[Int]] // unevaluated scala> println(x.size) 10000
結果の画像は一番下に貼っておきますが、まとめると
- LongMapの方が節約になるか?というと、そんなことはなく、ほぼ同じか、むしろ少しLongMapの方がメモリ使用量が多い
- どのオブジェクトが多いのか?をみるとわかりやすいが
- HashMapの方は "java.lang.Object" の配列の内部に実態を詰めていたりする
- LongMapはTipとBinというclassのinstanceが大量に出来ている
- TipとBinはこれ
private[immutable] case class Tip[+T](key: Long, value: T) extends LongMap[T] { // 中身省略 } private[immutable] case class Bin[+T](prefix: Long, mask: Long, left: LongMap[T], right: LongMap[T]) extends LongMap[T] { // 中身省略 }
- 詳細な構造はともかく、結局LongMapの方はTreeなので、1つのkey valueに対して1つのオブジェクトが出来てしまって、boxing自体は避けることが出来ているが、HashMapと比較したらオブジェクト数が多くなってしまう
- IntMapもあるが、おそらく同じ結論になるはず???(計測してない)
- mutable版は同じようなTreeではなさそうなので、違う結論になる可能性はなくもない?
- あくまでメモリの使用量だけ計測したが、メソッド呼び出しの速度がどうなるのか?は調べてない
- よく読むとscaladocに "This class is as of 2.8 largely superseded by HashMap." と書いてあります
- 多少関連する話として、AnyRefMapというのもあったけどHashMapの方が速くて少し前にdeprecatedになりしました
- HashMapすごいんだなぁ
- HashMapとロジック同じでIntやLongに特化させたら速いもの作れるのだろうか・・・?
- HashMapとLongMapのロジックの詳細は以下のリンクから
- LongMapは "Fast Mergeable Integer Maps" という1998年頃(?)の、かの有名な "Chris Okasaki" 先生の論文がベースぽい
- ちなみにScalaのHashMapは、HashMapというclass名はずっと同じだけれど、何度かロジック変わったり改善されています
- HashMap誰かの日本語記事もあるぞ
LongMap


HashMap


*1:少なくともimmutable版において