Какова наиболее эффективная библиотека сборников Java?

Какова самая эффективная библиотека сборников Java?

Несколько лет назад я сделал много Java и имел впечатление, что trove является лучшим (наиболее эффективным ) Реализация Java Collections. Но когда я прочитал ответы на вопрос "Самые полезные бесплатные библиотеки Java?" Я заметил, что trove не упоминается. Итак, какая библиотека библиотек Java теперь лучше?

ОБНОВЛЕНИЕ: Чтобы уточнить, я в основном хочу знать, какую библиотеку использовать, когда я должен хранить миллионы записей в хеш-таблице и т.д. (требуется небольшая продолжительность выполнения и объем памяти).

Ответ 1

От проверки, похоже, что Trove - это просто библиотека коллекций для примитивных типов - это не похоже на то, что она добавляет много функциональности по сравнению с обычными коллекциями в JDK.

Лично (и я предвзятый), я люблю Guava (включая прежний проект коллекций Google Java). Это делает различные задачи (включая коллекции) намного проще, что, по крайней мере, разумно эффективно. Учитывая, что операции коллекции редко составляют узкое место в моем коде (по моему опыту), это "лучше", чем API коллекций, который может быть более эффективным, но не делает мой код доступным для чтения.

Учитывая, что перекрытие между Trove и Guava довольно много, возможно, вы можете уточнить, что вы действительно ищете из библиотеки коллекций.

Ответ 2

Вопрос (сейчас) о хранении большого количества данных, которые могут быть представлены с использованием примитивных типов, таких как int, на Карте. Некоторые из ответов здесь, по моему мнению, очень вводят в заблуждение. Посмотрим, почему.

Я изменил бенчмарк с trove, чтобы измерить как время работы, так и потребление памяти. Я также добавил PCJ к этому эталону, который представляет собой еще одну библиотеку коллекций для примитивных типов (я использую этот экстенсивно). "Официальный" контрольный ориентир не сравнивает IntIntMaps с Java Collection Map<Integer, Integer>, возможно, сохранение Integers и сохранение ints не совпадают с технической точки зрения. Но пользователь может не заботиться об этой технической детали, он хочет эффективно хранить данные, представленные с помощью ints.

Сначала соответствующая часть кода:

new Operation() {

     private long usedMem() {
        System.gc();
        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
     }

     // trove
     public void ours() {
        long mem = usedMem();
        TIntIntHashMap ours = new TIntIntHashMap(SET_SIZE);
        for ( int i = dataset.size(); i-- > 0; ) {
           ours.put(i, i);
        }
        mem = usedMem() - mem;
        System.err.println("trove " + mem + " bytes");
        ours.clear();
     }

     public void pcj() {
        long mem = usedMem();
        IntKeyIntMap map = new IntKeyIntOpenHashMap(SET_SIZE);
        for ( int i = dataset.size(); i-- > 0; ) {
           map.put(i, i);
        }
        mem = usedMem() - mem;
        System.err.println("pcj " + mem + " bytes");
        map.clear();
     }

     // java collections
     public void theirs() {
        long mem = usedMem();
        Map<Integer, Integer> map = new HashMap<Integer, Integer>(SET_SIZE);
        for ( int i = dataset.size(); i-- > 0; ) {
           map.put(i, i);
        }
        mem = usedMem() - mem;
        System.err.println("java " + mem + " bytes");
        map.clear();
     }

Я предполагаю, что данные поступают как примитивные ints, что кажется разумным. Но это подразумевает штраф за время исполнения для java util, из-за автоматического бокса, который не обязательно для каркасов примитивных коллекций.

Результаты выполнения (без вызовов gc(), конечно) на WinXP, jdk1.6.0_10:

                      100000 put operations      100000 contains operations 
java collections             1938 ms                        203 ms
trove                         234 ms                        125 ms
pcj                           516 ms                         94 ms

Хотя это уже может показаться резким, это не является основанием для использования такой структуры.

Причина - производительность памяти. Результаты для карты, содержащей записи 100000 int:

java collections        oscillates between 6644536 and 7168840 bytes
trove                                      1853296 bytes
pcj                                        1866112 bytes

Для коллекций Java требуется более трех раз память по сравнению с базой примитивных коллекций. То есть вы можете хранить в три раза больше данных в памяти, не прибегая к дискам IO, что снижает производительность во время выполнения по величинам. И это имеет значение. Прочтите highscalability, чтобы узнать, почему.

По моему опыту высокая потребляемая память является самой большой проблемой производительности с Java, что, конечно же, приводит к ухудшению производительности во время работы. Примитивные структуры коллекции могут действительно помочь здесь.

Итак: Нет, java.util не является ответом. И "добавление функциональности" в коллекции Java не является вопросом, когда вы спрашиваете об эффективности. Кроме того, в современных коллекциях JDK не выходят даже специализированные коллекции Trove ".

Отказ от ответственности: Тест здесь далеко не полный, и он не идеален. Он предназначен для того, чтобы довести дело до конца, что я испытал во многих проектах. Примитивные коллекции достаточно полезны для терпимости к fishy API - , если вы работаете с большим количеством данных.

Ответ 3

Я знаю, что это старый пост, и здесь есть тонна ответов. Но ответы выше поверхностны и более упрощены с точки зрения предложения библиотеки. Существует не одна библиотека, которая хорошо справляется с различными показателями, представленными здесь. Единственный вывод, который я получаю, - это если вы заботитесь о производительности и памяти и, в частности, занимаетесь примитивными типами, более чем стоить рассматривать альтернативы не-jdk.

Вот более разумный анализ с точки зрения эталонных механиков и библиотек. Это является нитью в списке разработчиков mahout.

Раскрываемые библиотеки

  • HPPC
  • Trove
  • FastUtil
  • Mahout (Colt)
  • Коллекции Java

Обновление Июнь 2015: К сожалению, исходные тесты больше недоступны и, кроме того, немного устарели. Здесь - довольно недавние (янв. 2015) тесты, сделанные кем-то другим. Это не так всеобъемлюще, и у него нет интерактивных поисковых инструментов в качестве исходной ссылки.

Ответ 4

Как заметили другие комментаторы, определение "эффективный" отличает широкую сеть. Однако никто еще не упомянул Javolution library.

Некоторые из основных моментов:

  • Классы Javolution являются быстрыми, очень быстрыми (например, вставка/удаление текста в O [Log (n)] вместо O [n] для стандартного StringBuffer/StringBuilder).
  • Все классы Javolution являются жесткими в режиме реального времени и имеют очень детерминированное поведение (в микросекундном диапазоне). Кроме того (в отличие от стандартной библиотеки) Javolution является безопасным RTSJ (при использовании с расширением Java Real-Time не происходит утечки памяти или утечки памяти).
  • Классы сбора данных реального времени Javolution (карта, список, таблица и множество) могут использоваться вместо большинства стандартных классов коллекций и предоставлять дополнительную функциональность.
  • Коллекции Javolution предоставляют concurrency гарантии упрощения реализации параллельных алгоритмов.

В дистрибутив Javolution включен набор тестов, чтобы вы могли видеть, как они складываются с другими библиотеками/встроенными коллекциями.

Ответ 5

Некоторые коллекции libs для рассмотрения:

В первую очередь я хотел бы получить библиотеку коллекции JDK. Он охватывает наиболее распространенные вещи, которые вам нужно сделать и, очевидно, уже доступен вам.

Коллекции Google, вероятно, являются лучшей высококачественной библиотекой вне JDK. Он широко используется и хорошо поддерживается.

Коллекции Apache Commons старше и немного страдают от проблемы "слишком много поваров", но также имеют много полезного материала.

Trove имеет очень специализированные коллекции для таких случаев, как примитивные ключи/значения. В наши дни мы обнаруживаем, что на современных JDK и с коллекциями Java 5+ и параллельными вариантами использования коллекции JDK вытесняют даже специализированные коллекции Trove.

Если у вас действительно высокие варианты использования concurrency, вам обязательно нужно проверить такие вещи, как NonBlockingHashMap в высокоуровневой библиотеке lib, которая является блокировкой и может топать на ConcurrentHashMap, если у вас есть правильный вариант использования для он.

Ответ 6

java.util

Извините за очевидный ответ, но для большинства применений более чем достаточно Java Collections.

Ответ 9

В зависимости от того, как мы определяем "эффективный".

Каждая структура данных имеет собственное поведение Big-Oh для чтения, записи, итерации, объема памяти и т.д. Связанный список в одной библиотеке, вероятно, будет таким же, как и любой другой. И хэш-карта будет быстрее для чтения O (1), чем связанный список O (n).

Но когда я прочитал ответы на вопрос "Самые полезные бесплатные библиотеки Java?" Я заметил, что о нем трудно сказать.

Это не похоже на "наиболее эффективный". Это звучит как "самый популярный" для меня.

Только некоторые отзывы - я никогда не слышал об этом, и я не знаю никого, кто его использовал. Коллекции, встроенные в JDK, Google или Apache Commons, хорошо известны мне.

Ответ 10

Trove предлагает несколько преимуществ.

  • меньший объем памяти, он не использует объекты Map.Entry
  • вы можете использовать хеш-стратегии вместо ключей для карт, это экономит память и означает, что вам не нужно определять новый ключ каждый раз, когда вы хотите кэшировать объект по новому набору его атрибутов.
  • он имеет примитивные типы коллекций
  • Думаю, что у него есть форма внутреннего итератора

Тем не менее, многое было сделано для улучшения коллекций jdk, поскольку была написана.

Это стратегии хэширования, которые делают его привлекательным для меня, хотя... Google заработает и прочитает их обзор.

Ответ 11

ConcurrentHashMap, а также пакет java.util.concurrent следует упомянуть, если вы планируете использовать HashMap в нескольких потоках. ограниченный объем памяти, поскольку это часть стандартной java.

Ответ 12

Если вы хотите хранить миллионы записей в хеш-таблице, скорее всего, вы столкнетесь с проблемами памяти. Это случилось со мной, когда я попытался создать карту с 2,3 миллионами объектов String, например. Я пошел с BerkeleyDB, который очень зрелый и хорошо работает. У них есть API Java, который обертывает API Collections, поэтому вы можете легко создавать произвольно большие карты с очень небольшим объемом памяти. Доступ будет медленнее, хотя (поскольку он хранится на диске).

Последующий вопрос: есть ли достойная (и эффективная), ухоженная библиотека для неизменных коллекций? Clojure имеет отличную поддержку для этого, и было бы неплохо иметь что-то подобное для Java.