Vejledning til FastUtil

1. Introduktion

I denne vejledning ser vi på FastUtil bibliotek.

Først koder vi nogle eksempler på dens typespecifikke samlinger.

Derefter analyserer vi ydeevne, der giver FastUtil dens navn.

Lad os endelig kigge på FastUtil'S BigArray forsyningsselskaber.

2. Funktioner

Det FastUtil Java-biblioteket søger at udvide Java Collections Framework. Det giver typespecifikke kort, sæt, lister og køer med et mindre hukommelsesaftryk og hurtig adgang og indsættelse. FastUtil giver også et sæt af hjælpeprogrammer til at arbejde med og manipulere store (64-bit) arrays, sæt og lister.

Biblioteket indeholder også en en lang række praktiske input / output klasser til binære filer og tekstfiler.

Dens seneste udgivelse, FastUtil 8, frigav også et væld af typespecifikke funktioner, der udvidede JDK'erne Funktionelle grænseflader.

2.1. Fart

I mange tilfælde er FastUtil implementeringer er den hurtigste tilgængelige. Forfatterne har endda leveret deres egen dybdegående benchmarkrapport og sammenlignet den med lignende biblioteker HPPC og Trove.

I denne vejledning ser vi på at definere vores egne benchmarks ved hjælp af Java Microbench Harness (JMH).

3. Fuld størrelse afhængighed

Oven på det sædvanlige JUnit afhængighed, bruger vi FastUtils og JMH afhængigheder i denne vejledning.

Vi har brug for følgende afhængigheder i vores pom.xml fil:

 it.unimi.dsi fastutil 8.2.2 org.openjdk.jmh jmh-core 1.19 test org.openjdk.jmh jmh-generator-annprocess 1.19 test 

Eller for Gradle-brugere:

testCompile-gruppe: 'org.openjdk.jmh', navn: 'jmh-core', version: '1.19' testCompile-gruppe: 'org.openjdk.jmh', navn: 'jmh-generator-annprocess', version: '1.19' kompilere gruppe: 'it.unimi.dsi', navn: 'fastutil', version: '8.2.2'

3.1. Tilpasset krukkefil

På grund af manglen på generiske lægemidler, FastUtils genererer et stort antal typespecifikke klasser. Og desværre fører dette til en enorm krukkefil.

Men heldigvis for os, FastUtils inkluderer en find-deps.sh script, der tillader generering af mindre, mere fokuserede krukker bestående af kun de klasser, vi vil bruge i vores applikation.

4. Typespecifikke samlinger

Før vi begynder, lad os kigge hurtigt på den enkle proces med at starte en typespecifik samling. Lad os vælge en HashMap der gemmer nøgler og værdier ved hjælp af fordobler.

Til dette formål, FastUtils giver en Double2DoubleMap interface og en Double2DoubleOpenHashMap implementering:

Double2DoubleMap d2dMap = ny Double2DoubleOpenHashMap ();

Nu hvor vi har instantificeret vores klasse, kan vi simpelthen udfylde data, som vi ville med enhver Kort fra Java Collections API:

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

Endelig kan vi kontrollere, at dataene er tilføjet korrekt:

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

4.1. Ydeevne

FastUtils fokuserer på dets performante implementeringer. I dette afsnit bruger vi JMH til at verificere dette faktum. Lad os sammenligne Java-samlingerne HashSet implementering mod FastUtil's IntOpenHashSet.

Lad os først se, hvordan du implementerer IntOpenHashSet:

@Param ({"100", "1000", "10000", "100000"}) offentlig int setSize; @Benchmark public IntSet givenFastUtilsIntSetWithInitialSizeSet_whenPopulated_checkTimeTaken () {IntSet intSet = new IntOpenHashSet (setSize); for (int i = 0; i <setSize; i ++) {intSet.add (i); } returner intSet; }

Ovenfor har vi simpelthen erklæret IntOpenHashSet gennemførelse af IntSet interface. Vi har også erklæret den oprindelige størrelse sæt størrelse med @Param kommentar.

Kort sagt, disse tal indføres i JMH for at producere en række benchmarktest med forskellige sætstørrelser.

Næste, lad os gøre det samme ved hjælp af implementeringen af ​​Java Collections:

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

Lad os endelig køre benchmarket og sammenligne de to implementeringer:

Benchmark (setSize) Mode Cnt Score Enheder givetCollectionsHashSetWithInitialSizeSet ​​... 100 avgt 2 1.460 us / op givenCollectionsHashSetWithInitialSizeSet ​​... 1000 avgt 2 12.740 us / op givenCollectionsHashSetWithInitialSizeSet ​​... 10000 avgt 2 109.803 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 givenFastSupportSupport

Disse resultater gør det klartFastUtils implementering er meget mere performant end Java Collections-alternativet.

5. Store samlinger

En anden vigtig funktion af FastUtils er evnen til at bruge 64-bit arrays. Arrays i Java er som standard begrænset til 32 bit.

For at komme i gang, lad os se på BigArrays klasse til Heltal typer. IntBigArrays giver statiske metoder til at arbejde med 2-dimensionelle Heltal arrays. Ved at bruge disse leverede metoder kan vi i det væsentlige pakke vores array ind i et mere brugervenligt 1-dimensionelt array.

Lad os se på, hvordan dette fungerer.

Først starter vi med at initialisere et 1-dimensionelt array og konvertere det til et 2-dimensionelt array ved hjælp af IntBigArray's wrap metode:

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

Vi skulle Sørg for at bruge klon metode til at sikre en dyb kopi af arrayet.

Nu, som vi ville gøre med en Liste eller a Kort, kan vi få adgang til elementerne ved hjælp af metode:

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

Lad os endelig tilføje nogle kontroller for at sikre vores IntBigArray returnerer de korrekte værdier:

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

6. Konklusion

I denne artikel har vi taget en dykke ned i FastUtils kerneegenskaber.

Vi kiggede på nogle af typespecifikke samlinger, der FastUtil tilbud, inden du leger med nogle BigCollections.

Som altid kan koden findes på GitHub


$config[zx-auto] not found$config[zx-overlay] not found