2012-08-24

Long.bitCount(long) の速度

Java の Long.bitCount(long) が POPCNT にコンパイルされるとのことで、速度を簡易的に計ってみた。

比較対象は次の3つ。
  1. Long.bitCount(long)
  2. Long.bitCount(long) のソースをコピーして作った関数
  3. it.unimi.dsi.bits.Fast.count(long) 
Oracle Java 7u6 での速度比(小さいほど速い)は、
  1. 278
  2. 2269
  3. 1636
になった。

Long.bitCount(long) の呼び出しが BIOS コールのエミュレーションのように POPCNT に変換されているのかな?

ついでに dsiutils-2.0.7.jar の it.unimi.dsi.bits.Fast.count(long) も計測したんだけど、意外にも速かった。「broadword algorithm」というのは、Java ライブラリの実装アルゴリズムよりも速いんだろうか?
Broadword implementation of rank/select queries
http://vigna.dsi.unimi.it/papers.php#VigBIRSQ
ざくっと計ったので、参考まで。

rank/select の実装

rank/select の実装を探していて、Sux4J というライブラリがあった。
Sux: Implementing Succinct Data Structures
http://sux.di.unimi.it/
参考までに sux4j-3.0.4-sources.jar のソースをちょっと読んだんだけど、it.unimi.dsi.sux4j.bits.Rank16 の59行目の計算間違いでメモリを余分に確保しているような気が…。

僕の気のせいかもしれないので、そっとしておこう。

Java の Long.bitCount(long) と POPCNT

Java の Long.bitCount(long) は最新の CPU だと POPCNT にコンパイルしてくれて、「すごい!」とか感心してたんだけど、つい先日までバグがあってションボリだった。しかも、デフォルトでこの最適化はオンになってたし…。
java - Optimizing Long.bitCount - Stack Overflow
http://stackoverflow.com/questions/4839128/optimizing-long-bitcount
Bug ID: 7063674 Wrong results from basic comparisons after calls to Long.bitCount(long)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7063674
Oracle Java 7u6 では直っているらしい。

Succinct Data Structure な方は計ってみてるといいかも。

FilterOutputStream.close() では flush() の例外が潰されている

FilterOutputStream.close() のソースを読んでいたら、クローズ時の flush() の例外が潰されていてショック。

ググったら、バグデータベースにあった。
Bug ID: 6390383 (spec) FilterOutputStream.close() silently ignores flush() exceptions
http://bugs.sun.com/view_bug.do?bug_id=6390383
2006年の報告で、Oracle JDK 7u6でも放置ということは、直す気はないのかなぁ。