Guia do FastUtil

Guia do FastUtil

1. Introdução

Neste tutorial, vamos olhar para a bibliotecaFastUtil .

Primeiro, vamos codificar alguns exemplos de seustype-specific collections.

Então, vamos analisar operformance that gives FastUtil its name.

Finalmente, vamos dar uma olhada emFastUtil‘s BigArray utilities.

2. Recursos

A biblioteca JavaFastUtil busca estender o Java Collections Framework. Ele fornece aotype-specific maps, sets, lists and queues uma pegada de memória menor e acesso e inserção rápidos. FastUtil also fornece um conjunto deutilities for working with and manipulating large (64-bit) arrays, sets and lists.

A biblioteca também inclui ummultitude of practical Input/Output classes para arquivos binários e de texto.

Seu lançamento mais recente,FastUtil 8,, também lançou um host detype-specific functions, estendendo oFunctional Interfaces. do JDK

2.1. Rapidez

In many cases, the FastUtil implementations are the fastest available. Os autores forneceram até mesmo seus própriosbenchmark report em profundidade, comparando-os com bibliotecas semelhantes que incluemHPPC andTrove.

Neste tutorial, vamos definir nossos próprios benchmarks usandoJava Microbench Harness (JMH).

3. Dependência de tamanho completo

Além da dependência usual deJUnit, estaremos usandoFastUtilseJMHdependencies neste tutorial.

Vamos precisar das seguintes dependências em nossopom.xml file:


    it.unimi.dsi
    fastutil
    8.2.2


    org.openjdk.jmh
    jmh-core
    1.19
    test


    org.openjdk.jmh
    jmh-generator-annprocess
    1.19
    test

Ou para usuários 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. Arquivo Jar personalizado

Devido à falta de genéricos,FastUtils gera um grande número de classes específicas do tipo. E, infelizmente, isso leva a umhuge jar file.

No entanto, felizmente para nós,FastUtils includes a find-deps.sh script which allows generation of smaller, more focused jars compreende apenas as classes que queremos usar em nosso aplicativo.

4. Coleções específicas de tipo

Antes de começar, vamos dar uma olhada rápida emsimple process of instantiating a type-specific collection. Vamos escolher umHashMap que armazena chaves e valores usandodoubles. 

Para este propósito,FastUtils oferece umaDouble2DoubleMap interface e umaDouble2DoubleOpenHashMap implificação:

Double2DoubleMap d2dMap = new Double2DoubleOpenHashMap();

Agora que instanciamos nossa classe, podemos simplesmente preencher os dados como faríamos com qualquerMap  da API de coleções Java:

d2dMap.put(2.0, 5.5);
d2dMap.put(3.0, 6.6);

Por fim, podemos verificar se os dados foram adicionados corretamente:

assertEquals(5.5, d2dMap.get(2.0));

4.1. atuação

FastUtils focuses on its performant implementations. In this section, we’ll make use of the JMH to verify that fact. Vamos comparar a implementação deHashSet<Integer> das coleções Java contraFastUtil’s IntOpenHashSet.

Primeiro, vamos ver como implementar oIntOpenHashSet:

@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;
}

Acima, nós simplesmente declaramos a implementaçãoIntOpenHashSet da face sinterizadaIntSet . Também declaramos o tamanho inicialsetSize com a anotação@Param .

Simplificando, esses números são inseridos no JMH para produzir uma série de testes de benchmark com diferentes tamanhos de conjunto.

A seguir,let’s do the same thing using the Java Collections implementation:

@Benchmark
public Set givenCollectionsHashSetWithInitialSizeSet_whenPopulated_checkTimeTaken() {
    Set intSet = new HashSet<>(setSize);
    for(int i = 0; i < setSize; i++) {
        intSet.add(i);
    }
    return intSet;
}

Finalmente, vamos executar o benchmark e comparar as duas implementações:

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

Esses resultados tornam claro o FastUtils implementation is much more performant than the Java Collections alternative.

5. Grandes coleções

Outro importantefeature of FastUtils is the ability to use 64-bit arrays. Arrays em Java, por padrão, são limitados a 32 bits.

Para começar, vamos dar uma olhada na classeBigArrays para os tiposInteger. IntBigArrays provides static methods for working with 2-dimensional Integer arrays. Usando esses métodos fornecidos, podemos essencialmente agrupar nosso array em um array unidimensional mais amigável.

Vamos dar uma olhada em como isso funciona.

Primeiro, vamos começar inicializando uma matriz unidimensional e convertendo-a em uma matriz bidimensional usando o métodoIntBigArray’s wrap :

int[] oneDArray = new int[] { 2, 1, 5, 2, 1, 7 };
int[][] twoDArray = IntBigArrays.wrap(oneDArray.clone());

Devemosmake sure to use the clone method to ensure a deep copy of the array.

Agora, como faríamos comList ou aMap, podemos obter acesso aos elementos usando o métodoget :

int firstIndex = IntBigArrays.get(twoDArray, 0);
int lastIndex = IntBigArrays.get(twoDArray, IntBigArrays.length(twoDArray)-1);

Finalmente, vamos adicionar algumas verificações para garantir que nossoIntBigArray retorne os valores corretos:

assertEquals(2, firstIndex);
assertEquals(7, lastIndex);

6. Conclusão

Neste artigo, pegamos umdive into FastUtils core features.

Vimos alguns dostype-specific collections that FastUtil offers, before playing around with some BigCollections.

Como sempre, o código pode ser encontrado emGitHub