Клонирование int [] - кто-нибудь получил более быстрое предложение? - PullRequest
4 голосов
/ 27 мая 2011

Я смотрю на профиль, где одна из горячих точек процессора - это функция, которая состоит в клонировании окончательного статического целого []. Вы можете спросить: «Почему?» вызывающие стороны используют результаты в качестве отправной точки процесса хеширования.

Другими словами, код должен сделать (логически):

  1. создать новый массив
  2. получить семена хэша (столько, сколько размер массива)
  3. поместите значения в новый массив, рассчитанный по хэш-семенам. Это итеративный Алгоритм, так что выгодно иметь начальные числа в массиве - и, следовательно, идея начать с клона массива начальных чисел.

Прежде чем я перестану или начну писать микробенчмарки, я отправлю этот вопрос на тот случай, если у кого-нибудь есть какие-то особые знания о том, что скрывается под clone (), в сравнении с Arrays.copyOf, по сравнению с просто новым и массивом-копией.

Ответы [ 4 ]

5 голосов
/ 27 мая 2011

Arrays.copyOf использует memcopy как инструкции под капотом.Более того, существует меньше проверок индекса вне границ.Если вы присваиваете значения один за другим, то каждый раз выполняется «ограниченная» проверка.

Я не проводил сравнительный анализ для каждого из предложенных вариантов, но я уверен, что Arrays.copyOf() будет быстреечем new int[] + for(...).

С другой стороны, я не уверен, что Arrays.copyOf() будет более эффективным, чем int[] myCopy = myOrig.clone(), поскольку клонирование происходит в массиве примитивного типа.Существует высокая вероятность того, что компилятор сгенерирует оптимизированный байт-код.Только тесты дадут окончательный ответ.

3 голосов
/ 27 мая 2011

Arrays.copyOf использует System.arraycopy, но сначала добавляет несколько проверок

public static int[] copyOf(int[] original,
    int newLength) 
{
        if (0 < = newLength) {
            return copyOfRange(original, 0, newLength);
        }
        throw new NegativeArraySizeException();
}


public static int[] copyOfRange(int[] original,
    int start,
    int end) 
{
        if (start < = end) {
            if (original.length  >= start && 0 < = start) {
                int length = end - start;
                int copyLength = Math.min(length, original.length - start);
                int[] copy = new int[length];
                System.arraycopy(original, start, copy, 0, copyLength);
                return copy;
            }
            throw new ArrayIndexOutOfBoundsException();
        }
        throw new IllegalArgumentException();
}

Я получил это от http://www.docjar.com/docs/api/java/util/Arrays.html, поэтому может быть незначительно лучше использовать это, чемArrays.copyOf

int[] newone = new int[orig.length];
System.arraycopy(orig, 0, newone , 0, orig.length);

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

0 голосов
/ 27 мая 2011

Использование clone() для массивов примитивных типов примерно на 50% медленнее, чем комбинация new [] и System.arraycopy с виртуальной машиной клиента Java 1.6 / 1.7 x86, но примерно с той же скоростью, что и с виртуальной машиной сервера x64.

Для массивов размером в несколько тысяч элементов или менее копирование является самой дорогой частью операции, а создание самого массива (т.е. создание байтового массива из 2048 элементов занимает в 3 раза больше времени, чемскопировать 2048 элементов в System.arraycopy).Так что вы могли бы получить некоторое улучшение, если бы вы перерабатывали временные массивы.

0 голосов
/ 27 мая 2011

Если код принадлежит вам, как насчет следующего:

public final class ReadOnlyIntArray {
  private final int[] _contents;

  public ReadOnlyIntArray(int[] data) {
    _contents = (int[]) data.clone();
  }

  public int get(int index) {
    return _contents[index];
  }
}

Сохраните содержимое final static в одном из них и верните этот объект вместо int[].Заставьте потребителя клонировать, если он сделает что-нибудь разрушительное.

Я часто чувствовал, что эта конструкция должна была быть одной из основных конструкций в java.lang, что позволило бы коду, который возвращает Class[], Method[] и т. Д., Чтобы не нужно было каждый раз клонировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...