FastUtilのガイド

1. 前書き

このチュートリアルでは、__ http://fastutil.di.unimi.it/ [FastUtil] __libraryを確認します。
最初に、* type-specific collections *の例をいくつかコーディングします。
次に、__ FastUtil __itsという名前を与える*パフォーマンスを分析します*
最後に、* _ FastUtil_’s __BigArray __utilities。*を見てみましょう。

2. 特徴

_FastUtil_ Javaライブラリは、Java Collections Frameworkの拡張を目指しています。 これは、メモリフットプリントが小さく、アクセスと挿入が高速な*タイプ固有のマップ、セット、リスト、およびキュー*を提供します。 __FastUtil __には、大きな(64ビット)配列、セット、リストを操作および操作するための*ユーティリティのセットも用意されています。*
このライブラリには、バイナリおよびテキストファイル用の*実用的な入出力クラス*が含まれています。
最新リリース_FastUtil 8、_は、http://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/Function.html [type-specific functions]のホストもリリースし、JDKの_httpsを拡張しました。 //docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html [機能インターフェイス] ._

2.1. 速度

*多くの場合、__FastUtil __implementationsは最も高速です。*著者は独自の詳細なhttp://java-performance.info/hashmap-overview-jdk-fastutil-goldman-sachs-hppc-koloboke- trove-january-2015 / [ベンチマークレポート]、類似のライブラリとの比較には__HPPC __andand__Trove._が含まれます
このチュートリアルでは、https://www.baeldung.com/java-microbenchmark-harness [Java Microbench Harness(JMH)]を使用して独自のベンチマークを定義します。

3. 完全なサイズの依存関係

通常の_JUnit_依存関係に加えて、https://search.maven.org/search?q = g:it.unimi.dsi%20AND%20a:fastutil [_FastUtils_]および_https:// searchを使用します。 .maven.org / search?q = a:jmh-core%20OR%20a:jmh-generator-annprocess [JMH] _ https://search.maven.org/search?q=a:jmh-core%20OR% 20a:jmh-generator-annprocess [dependencies]このチュートリアル。
__pom.xml __fileには次の依存関係が必要です。
<dependency>
    <groupId>it.unimi.dsi</groupId>
    <artifactId>fastutil</artifactId>
    <version>8.2.2</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.19</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.19</version>
    <scope>test</scope>
</dependency>
またはGradleユーザーの場合:
testCompile group: 'org.openjdk.jmh', name: 'jmh-core', version: '1.19'
testCompile group: 'org.openjdk.jmh', name: 'jmh-generator-annprocess', version: '1.19'
compile group: 'it.unimi.dsi', name: 'fastutil', version: '8.2.2'

3.1. カスタマイズされたjarファイル

ジェネリックがないため、__FastUtils ___は多数のタイプ固有のクラスを生成します。 残念ながら、これは*巨大なjarファイル*につながります。
ただし、幸運なことに、__ FastUtils __ **には__find-deps.sh __scriptが含まれています。これにより、アプリケーションで使用するクラスのみで構成される、より小さく、より焦点の合ったjarを生成できます。

4. タイプ固有のコレクション

始める前に、https://www.baeldung.com/java-map-primitives [型固有のコレクションをインスタンス化する簡単なプロセス]を簡単に見てみましょう。 _doublesを使用してキーと値を保存する_HashMap_を選択しましょう。 _
この目的のために、__FastUtils __は__http://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/doubles/Double2DoubleMap.html [Double2DoubleMap] __interfaceおよびa __http://fastutil.di.unimiを提供します。 it / docs / it / unimi / dsi / fastutil / doubles / Double2DoubleOpenHashMap.html [Double2DoubleOpenHashMap] __implementation:
Double2DoubleMap d2dMap = new Double2DoubleOpenHashMap();
クラスをインスタンス化したので、Java Collections APIの__Map ___を使用してデータを入力するだけです。
d2dMap.put(2.0, 5.5);
d2dMap.put(3.0, 6.6);
最後に、データが正しく追加されたことを確認できます。
assertEquals(5.5, d2dMap.get(2.0));

4.1. パフォーマンス

  • FastUtils_は、パフォーマンスの実装に焦点を当てています。 このセクションでは、その事実を検証するためにJMHを使用します。 /fastutil/ints/IntOpenHashSet.html[_IntOpenHashSet]。

    最初に、_IntOpenHashSet:_の実装方法を見てみましょう。
@Param({"100", "1000", "10000", "100000"})
public int setSize;

@Benchmark
public IntSet givenFastUtilsIntSetWithInitialSizeSet_whenPopulated_checkTimeTaken() {
    IntSet intSet = new IntOpenHashSet(setSize);
    for(int i = 0; i < setSize; i++) {
        intSet.add(i);
    }
    return intSet;
}
上記では、__IntSet ___interfaceの_IntOpenHashSet_実装を宣言しただけです。 また、__ @ Param __annotationを使用して初期サイズ___setSize ___を宣言しました。
簡単に言えば、これらの数値はJMHに入力され、異なるセットサイズで一連のベンチマークテストが生成されます。
次に、* Java Collectionsの実装を使用して同じことをしましょう:*
@Benchmark
public Set<Integer> givenCollectionsHashSetWithInitialSizeSet_whenPopulated_checkTimeTaken() {
    Set<Integer> intSet = new HashSet<>(setSize);
    for(int i = 0; i < setSize; i++) {
        intSet.add(i);
    }
    return intSet;
}
最後に、ベンチマークを実行して、2つの実装を比較しましょう。
Benchmark                                     (setSize)  Mode  Cnt     Score   Units
givenCollectionsHashSetWithInitialSizeSet...        100  avgt    2     1.460   us/op
givenCollectionsHashSetWithInitialSizeSet...       1000  avgt    2    12.740   us/op
givenCollectionsHashSetWithInitialSizeSet...      10000  avgt    2   109.803   us/op
givenCollectionsHashSetWithInitialSizeSet...     100000  avgt    2  1870.696   us/op
givenFastUtilsIntSetWithInitialSizeSet...           100  avgt    2     0.369   us/op
givenFastUtilsIntSetWithInitialSizeSet...          1000  avgt    2     2.351   us/op
givenFastUtilsIntSetWithInitialSizeSet...         10000  avgt    2    37.789   us/op
givenFastUtilsIntSetWithInitialSizeSet...        100000  avgt    2   896.467   us/op
これらの結果から、** __FastUtils ___implementationがJavaコレクションの代替よりもはるかにパフォーマンスが高いことが明確になります。**

5. ビッグコレクション

__ ** Fa ** stUtils __のもう1つの重要な機能は、64ビット配列を使用できることです。* Javaの配列は、デフォルトでは32ビットに制限されています。
始めるために、_Integer_型の_BigArrays_クラスを見てみましょう。 * http://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/ints/IntBigArrays.html [_IntBigArrays_]は、2次元_Integer_配列を操作するための静的メソッドを提供します。*これらの提供されたメソッドを使用することにより、基本的に、配列をより使いやすい1次元配列にラップできます。
これがどのように機能するかを見てみましょう。
まず、1次元配列を初期化し、__ IntBigArrayのwrap __methodを使用して2次元配列に変換します。
int[] oneDArray = new int[] { 2, 1, 5, 2, 1, 7 };
int[][] twoDArray = IntBigArrays.wrap(oneDArray.clone());
  • _clone_メソッドを使用して、配列の深いコピーを確実にする必要があります。*

    これで、__ List __またはa with_Map_で行うように、__get __methodを使用して要素にアクセスできます。
int firstIndex = IntBigArrays.get(twoDArray, 0);
int lastIndex = IntBigArrays.get(twoDArray, IntBigArrays.length(twoDArray)-1);
最後に、__ IntBigArray ___が正しい値を返すことを確認するためのチェックを追加しましょう。
assertEquals(2, firstIndex);
assertEquals(7, lastIndex);

6. 結論

この記事では、__FastUtils ___coreの機能を詳しく見ていきます。*
_BigCollections _。*をいじる前に、_FastUtil_が提供する* type-specificコレクションのいくつかを見ました。
いつものように、コードはhttps://github.com/eugenp/tutorials/tree/master/libraries-primitive[GitHub]で見つけることができます