找到大量整数平均值的最佳方法是什么?

时间:2011-01-25 16:53:23

标签: java algorithm performance optimization

每个整数可以与整数本身的大小一样大(Java int-32位),因此将整数的总和存储在整数变量中不是一种选择。 我担心使用Java BigInts可能会严重影响性能。

现在我正在尝试分裂和征服,同时使用 long 存储总和。

有没有更好的解决方案?

8 个答案:

答案 0 :(得分:6)

BigInt非常快。正如我经常说的那样,先做好,然后进行配置和优化。

答案 1 :(得分:6)

您可以使用长(64位)来保存总和。如果你超支,BigInteger就是你要走的路。

答案 2 :(得分:4)

long数据类型怎么样?即使在32位机器上它也应该非常快。

答案 3 :(得分:2)

您可以使用浮点数,然后将结果转换回整数。这可能不是最佳的,但应该足够快(并且直截了当)

答案 4 :(得分:2)

如果你知道你必须提前平均的整数数量,你可以逐个进行划分

int [] a;
int average;
int remainder;
int alen = a.length;

for( int i = 0; i < alen; i++ ) {
  int q = a[i] / alen;  //calculate the quotient and the remainder for the current element
  int r = a[i] % alen;
  average += q; // add up the averages and the remainders
  remainder += r;
  if( remainder >= alen ) { //roll the average over if needed 
    remainder -= alen;
    average++;
  }
}

当然在实践中并不重要,因为数组中不能有超过2个 31 元素,这意味着您可以将总和存储在long。< / p>

答案 5 :(得分:0)

除非您计算数十亿数字的平均值,否则使用BigInteger不会对性能产生太大影响。您应该尝试使用BigInteger对其进行编码,然后确定它是否足够快。

答案 6 :(得分:0)

将浮点与Kahan's summation一起使用。

答案 7 :(得分:0)

您可以长时间存储超过2亿的整数。问题是什么? 好吧,如果你需要更多的注意力。做一个包含多个longs的简单类(和long []会做),并在第1个顶部添加。每增加几十亿,就会有一个新的长。

最后(平均)将BigInteger中的长数相加并除以。代码几乎没有开销,一个额外的计数器和一个额外的检查(预测的分支)。

[希望我没有因为1而愚蠢;)

package t1;

import java.math.BigInteger;
import java.util.Arrays;

public class Avg {
    long sum;
    long[] totals = new long[0];

    int counter;

    public void add(int v){
        if (counter++==Integer.MAX_VALUE){
            counter = 0;
            int len =totals.length;
            totals = Arrays.copyOf(totals, len+1);
            totals[len]=sum;
            sum = 0;
        }
        sum+=v;         
    }

    public int avg(){
        long count = this.counter;
        count+=totals.length*(long)Integer.MAX_VALUE;

        BigInteger sum = BigInteger.valueOf(this.sum);
        for (long subSum : totals)
            sum=sum.add(BigInteger.valueOf(subSum));

        return sum.divide(BigInteger.valueOf(count)).intValue();//tweak if you need be
    }
}