Хотя System.arraycopy
реализовано изначально и поэтому может быть 1 быстрее, чем цикл Java, это не всегда так быстро, как вы могли ожидать.Рассмотрим следующий пример:
Object[] foo = new Object[]{...};
String[] bar = new String[foo.length];
System.arraycopy(foo, 0, bar, 0, bar.length);
В этом случае базовый тип массивов foo
и bar
имеет разные базовые типы, поэтому реализация arraycopy
должна проверять тип каждой ссылкископировать, чтобы убедиться, что это на самом деле ссылка на экземпляр String.Это значительно медленнее, чем простая memcopy в стиле C. содержимого массива.
Другой момент заключается в том, что Arrays.copyOf
использует System.arraycopy
под капотом.Поэтому System.arraycopy
равно на первый взгляд не должно быть медленнее 2 , чем Arrays.copyOf
.Но вы можете видеть (из кода выше ), что Arrays.copyOf
в некоторых случаях будет использовать отражение для создания нового массива.Таким образом, сравнение производительности не является простым.
Есть несколько недостатков в этом анализе.
Мы смотрим на код реализации из конкретной версии Java.Эти методы могут измениться, сделав недействительными предыдущие предположения об эффективности.
Мы игнорируем возможность того, что JIT-компилятор может выполнить некоторую умную оптимизацию для этих методов.И, видимо, это происходит с Arrays.copyOf
;см. Почему Arrays.copyOf в 2 раза быстрее, чем System.arraycopy для небольших массивов? .Этот метод является «встроенным» в реализации Java текущего поколения, что означает, что JIT-компилятор будет игнорировать то, что находится в исходном коде Java!
Но в любом случае разница между двумя версиями равно O(1)
(т.е. не зависит от размера массива) и относительно мало.Поэтому я бы посоветовал использовать версию, которая делает ваш код проще для чтения, и беспокоиться только о том, какая из них быстрее, если profiling говорит вам, что это важно.
1 - может быть быстрее, но также возможно , что JIT-компилятор делает такую хорошую работу по оптимизации цикла кода вручную, что нет никакой разницы.