Почему Collections.addAll, как предполагается, быстрее, чем c.addAll

Java документы API говорит неотступно следование Collections.addAll

Поведение этого удобного метода идентично поведению c.addAll (Arrays.asList (элементы)), но этот метод, вероятно, будет работать значительно быстрее при большинстве реализаций.

Таким образом, если я понимаю правильно, a) медленнее, чем b):

a)

Collection col = new ArrayList();
col.addAll(Arrays.asList(1, 2, 3, 4, 5));

b)

Collection col = new ArrayList();
// Collections.addAll(col, Arrays.asList(1, 2, 3, 4, 5)); <-- won't compile
Collections.addAll(col, 1, 2, 3, 4, 5);

Кто-либо может объяснить мне, почему это?

отредактированный: исправленный пример кода. благодаря polygenelubricants

36
задан Community 23 May 2017 в 12:02
поделиться

2 ответа

Давайте подробнее рассмотрим два из них:

 // a)
col.addAll (Arrays.asList (1, 2, 3, 4, 5));

Вот что происходит:

  1. varags + autoboxing создает Integer []
  2. Arrays.asList создает List , поддерживаемый массивом
  3. addAll выполняет итерацию по Collection , используя Iterator
 // b)
Коллекции.addAll (столбец, 1, 2, 3, 4, 5);

Вот что происходит:

  1. varargs + autoboxing создает Integer []
  2. addAll выполняет итерацию по массиву (вместо Iterable )

Мы теперь можно увидеть, что б) может быть быстрее, потому что: вызов

  • Arrays.asList пропускается, т.е. не создается промежуточный Список .
  • Поскольку элементы заданы в массиве (благодаря механизму varargs), итерация по ним может быть быстрее, чем при использовании Iterator .

При этом, если профилирование не показывает иное, разница вряд ли будет «значительной». Не оптимизируйте преждевременно. Хотя классы Java Collection Framework могут быть медленнее, чем массивы, они работают более чем адекватно для большинства приложений.

Ссылки API

См. Также

Связанные вопросы


Сводка

  • Если вы добавляете элементы из массива, вы можете использовать Collections.addAll (col, arr)
    • Помните, что переменные также выполняются с использованием массивов
  • Если вы добавляете элементы из Коллекции , используйте col.addAll (otherCol)
    • Делайте НЕ например Collections.addAll (col, otherCol.toArray ())
      • Такой обходной путь, вероятно, будет медленнее!
  • Дело не в том, что один в высшей степени быстрее другого
    • Речь идет о пропуске ненужных шагов в текущей ситуации
49
ответ дан 27 November 2019 в 06:02
поделиться

Единственная причина, по которой он может быть быстрее, состоит в том, что он избегает вызова Arrays.asList, который должен быть относительно дешевым, поскольку он просто обертывает массив.Некоторые реализации Collection, например LinkedList, преобразуют переданную коллекцию обратно в массив перед добавлением элементов, что вызывает дополнительные накладные расходы.

С другой стороны, ArrayList.addAll выделяет необходимое пространство один раз перед добавлением каких-либо элементов, и поэтому должно быть намного быстрее, когда Collections.addAll требует многократного изменения размера резервного массива.

Таким образом, Collections.addAll может быть быстрее при многократном добавлении всего нескольких элементов в коллекцию, но я сомневаюсь, что этот случай когда-либо станет узким местом для производительности.

3
ответ дан 27 November 2019 в 06:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: