在Java中扩展数组的最有效方法?

[英]Most Efficient Way to Scale an Array in Java?


(Apologies if this has been asked before - I can't believe it hasn't, but I couldn't find one. Perhaps my search-fu is weak.)

(如果之前有人问过道歉 - 我无法相信它没有,但我找不到。也许我的搜索功能很弱。)

For years I've "known" that Java has no native function to scale an array (i.e. multiply each element by a constant). So I've been doing this:

多年来我一直“知道”Java没有缩放数组的本机函数(即将每个元素乘以常数)。所以我一直这样做:

for (int i=0; i<array.length; i++) {
  array[i] = array[i] * scaleFactor;
}

Is this actually the most efficient way (in this application, for example, it's an array of around 10000 doubles)? Or is there a better way?

这实际上是最有效的方式(例如,在这个应用程序中,它是一个大约10000个双倍的数组)?或者,还有更好的方法?

7 个解决方案

#1


13  

Looks absolutely fine to me. I can't think of a more efficient way. Obviously try to put that code in one place rather than having the actual code all over the place, but other than that, no obvious problems.

看起来对我很好。我想不出更有效的方法。显然尝试将代码放在一个地方而不是将实际代码放在一处,但除此之外,没有明显的问题。

#2


8  

Only other suggestion I can offer is to lazily scale whereby you only pay the cost of multiplication on accessing each element; e.g.

我可以提供的另一个建议是懒惰的比例,你只需支付乘法费用来访问每个元素;例如

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;
  }
}

Obviously this is only better in certain situations:

显然,这在某些情况下更好:

  • When your array is huge AND
  • 当你的阵列是巨大的AND
  • You are only accessing a few elements AND
  • 您只访问一些元素AND
  • You are typically accessing these elements once.
  • 您通常只访问这些元素一次。

In other situations it's a micro-optimisation with no real benefit on modern CPUs.

在其他情况下,它是一种微优化,对现代CPU没有任何实际好处。

#3


5  

The "better way" is to write array[i] *= scaleFactor; instead of array[i] = array[i] * scaleFactor;. :-)

“更好的方法”是编写array [i] * = scaleFactor;而不是array [i] = array [i] * scaleFactor;。 :-)

Really, that's just syntactic sugar though - the compiled output (and hence performance) should be exactly the same. As Jon says, you're not going to be able to get any better performance, but personally I'll take a reduction in typing any day.

实际上,这只是语法糖 - 编译后的输出(以及性能)应该完全相同。正如乔恩所说,你无法获得更好的表现,但就个人而言,我会减少任何一天的打字。

#4


3  

Only thing I can think to add in addition to Adamski and Jon Skeet is that if it happens to be an array of ints/longs and you're scaling by a power of 2, then you might get a slight improvement by using bitshift operators. YMMV though, since it will depend on the compiler (and possibly even the VM).

除了Adamski和Jon Skeet之外,我唯一可以想到的是,如果它恰好是一个整数/长整数并且你以2的幂进行缩放,那么你可以通过使用bitshift运算符来略微改进。但是YMMV,因为它将取决于编译器(甚至可能是VM)。

#5


0  

You could work with threads, to reduce the runtime, but the bottom line is you would include this code and let each thread run a part of the for loop so the resulting program is as efficient as yours; it's just made faster

您可以使用线程来减少运行时间,但最重要的是您将包含此代码并让每个线程运行for循环的一部分,以便生成的程序与您的一样高效;它变得更快了

#6


0  

Looks optimal to me.

对我来说看起来最合适

Don't fall for false optimisations like declaring the array length in a final field outside the loop. This works for Collections by avoiding repeat method calls to .size() and Strings avoiding method calls to .length() but on an array .length is already a public final field.

不要因为在循环外的最后一个字段中声明数组长度等错误优化而失败。这适用于集合,通过避免重复方法调用.size()和字符串,避免对.length()的方法调用,但在数组.length已经是公共最终字段。

Also, looping backwards towards zero might be an assembly language optimisation but in a high level language like Java the VM will take care of any obvious tweaks.

此外,向后循环向零可能是汇编语言优化,但在像Java这样的高级语言中,VM将处理任何明显的调整。

#7


0  

In Java 8:

在Java 8中:

double coef = 3.0;
double[] x1 = {1,2,3};
double[] x2 = DoubleStream.of(x1).map(d->d*coef).toArray();

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2011/10/17/6b4870a1f6f7ccfc4068fb4b2aa52971.html



 
© 2014-2018 ITdaan.com 粤ICP备14056181号