Ответ 1
Похоже на меня. Я не могу придумать более эффективный способ. Очевидно, постарайтесь поставить этот код в одном месте, вместо того, чтобы иметь реальный код повсюду, но кроме этого, никаких очевидных проблем.
(Извиняется, если это было задано раньше - я не могу поверить, что это не так, но я не смог найти его. Возможно, мой поисковый фью слабый.)
В течение многих лет я "знал", что Java не имеет встроенной функции для масштабирования массива (т.е. умножает каждый элемент на константу). Поэтому я делаю это:
for (int i=0; i<array.length; i++) {
array[i] = array[i] * scaleFactor;
}
Действительно ли это самый эффективный способ (в этом приложении, например, это массив около 10000 удваивается)? Или есть лучший способ?
Похоже на меня. Я не могу придумать более эффективный способ. Очевидно, постарайтесь поставить этот код в одном месте, вместо того, чтобы иметь реальный код повсюду, но кроме этого, никаких очевидных проблем.
Только другое предложение, которое я могу предложить, - это ленивый масштаб, при котором вы платите только стоимость умножения при доступе к каждому элементу; например.
public class MyArray {
private final double[] arr;
private double scale = 1.0;
public MyArray(double[] arr) {
this.arr = arr;
}
public double getScale() {
return scale;
}
public void setScale(double scale) {
this.scale = scale;
}
public double elementAt(int i) {
return arr[i] * scale;
}
}
Очевидно, что это только лучше в определенных ситуациях:
В других ситуациях это микро-оптимизация без реальной выгоды от современных процессоров.
"Лучшим способом" является запись array[i] *= scaleFactor;
вместо array[i] = array[i] * scaleFactor;
.: -)
Действительно, это просто синтаксический сахар, хотя - скомпилированный вывод (и, следовательно, производительность) должен быть точно таким же. Как говорит Джон, вы не сможете получить лучшую производительность, но лично я уменьшу написание в любой день.
Единственное, что я могу добавить в дополнение к Adamski и Jon Skeet, - это то, что если это массив массивов ints/longs, и вы масштабируетесь по мощности 2, то вы можете получить небольшое улучшение, используя операторы битрейта. YMMV, хотя, поскольку он будет зависеть от компилятора (и, возможно, даже от виртуальной машины).
Вы можете работать с потоками, чтобы сократить время выполнения, но в нижней строке вы должны включить этот код и позволить каждому потоку выполнять часть цикла for, чтобы получившаяся программа была такой же эффективной, как ваша; он просто ускорялся
Мне кажется оптимальным.
Не поддавайтесь ложным оптимизациям, таким как объявление длины массива в конечном поле вне цикла. Это работает для коллекций, избегая повторных вызовов методов в .size() и Strings, избегая вызовов методов в .length(), но в массиве .length уже является общедоступным конечным полем.
Кроме того, цикл назад к нулю может быть оптимизацией на языке ассемблера, но на языке высокого уровня, таком как Java, VM позаботится о любых очевидных трюках.
В Java 8:
double coef = 3.0;
double[] x1 = {1,2,3};
double[] x2 = DoubleStream.of(x1).map(d->d*coef).toArray();