Ръководство за FastUtil

1. Въведение

В този урок ще разгледаме библиотеката FastUtil .

Първо ще кодираме няколко примера за специфичните за него колекции.

След това ще анализираме производителността, която дава името на FastUtil .

И накрая, нека да вземе един поглед на FastUtil е BigArray комунални услуги.

2. Характеристики

В FastUtil Java библиотеката се стреми да разшири рамката на Java колекции. Той осигурява специфични за типа карти, набори, списъци и опашки с по-малък отпечатък на паметта и бърз достъп и вмъкване. FastUtil също така предоставя набор от помощни програми за работа и манипулиране на големи (64-битови) масиви, набори и списъци.

Библиотеката включва и множество практически класове за въвеждане / извеждане за двоични и текстови файлове.

Последната му версия, FastUtil 8, също пусна множество специфични за типа функции, разширявайки функционалните интерфейси на JDK .

2.1. Скорост

В много случаи реализациите на FastUtil са най-бързите от наличните. Авторите дори са предоставили свой собствен задълбочен доклад за сравнение, сравнявайки го с подобни библиотеки, включващи HPPC и Trove.

В този урок ще търсим да дефинираме собствените си еталони, използвайки Java Microbench Harness (JMH).

3. Пълноразмерна зависимост

На върха на обичайното за JUnit зависимостта, ние ще се използва най- FastUtils и JMH зависимости в този урок.

Ще ни трябват следните зависимости в нашия файл pom.xml :

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

Или за потребители на 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, който позволява генериране на по-малки, по-фокусирани буркани, състоящи се само от класовете, които искаме да използваме в нашето приложение.

4. Колекции, специфични за типа

Преди да започнем, нека да надникнем набързо в простия процес на създаване на екземпляр на специфична за типа колекция. Нека да изберем HashMap, която съхранява ключове и стойности с помощта на двойни.

За тази цел FastUtils осигурява Double2DoubleMap интерфейс и Double2DoubleOpenHashMap изпълнение:

Double2DoubleMap d2dMap = new Double2DoubleOpenHashMap();

Сега, когато създадохме пример за нашия клас, можем просто да попълним данни, както бихме направили с всяка карта от API на Java Collections:

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

И накрая, можем да проверим дали данните са добавени правилно:

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

4.1. производителност

FastUtils се фокусира върху изпълнението си. В този раздел ще използваме JMH, за да потвърдим този факт. Нека сравнимвнедряванетона Java Collections HashSet с IntOpenHashSet на FastUtil .

Първо, нека видим как да приложим 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; }

Над, ние сме просто обявява IntOpenHashSet изпълнението на IntSet интерфейс. Също така декларирахме началния размер setSize с анотацията @Param .

Казано по-просто, тези числа се подават в JMH, за да се получат поредица тестове за сравнение с различни размери.

След това нека направим същото, като използваме внедряването на Java Collections:

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

И накрая, нека стартираме бенчмарка и сравним двете имплементации:

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 е много по-ефективно от алтернативата на Java Collections.

5. Големи колекции

Друга важна характеристика на Fa stUtils е възможността да се използват 64-битови масиви. Масивите в Java по подразбиране са ограничени до 32 бита.

За да започнем, нека разгледаме класа BigArrays за Integer типове. IntBigArrays предоставя статични методи за работа с двумерни масиви Integer . Използвайки тези предоставени методи, ние можем по същество да обгърнем нашия масив в по-лесен за ползване едноизмерен масив.

Нека да разгледаме как работи това.

Първо, ще започнем с инициализиране на едноизмерен масив и превръщането му в двуизмерен масив с помощта на метода за обгръщане на IntBigArray :

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

Трябва да се погрижим да използваме метода на клониране , за да осигурим дълбоко копие на масива.

Сега, както бихме направили със списък или карта , можем да получим достъп до елементите, използвайки метода get :

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

И накрая, нека добавим няколко проверки, за да сме сигурни, че нашият IntBigArray връща правилните стойности:

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

6. Заключение

В тази статия се потопихме в основните функции на FastUtils .

Разгледахме някои от специфичните за типа колекции, които FastUtil предлага, преди да си поиграем с някои BigCollections .

Както винаги, кодът може да бъде намерен в GitHub