时间表现,10 000个元素的阵列,简单的应用程序

时间:2014-02-24 20:44:43

标签: java performance time

当我运行这段代码时,我得到了0.25秒的时间,我想改进这段代码以获得比0.16更好的时间 - 这是限制。我知道这取决于硬件。时间是计算而不填充数组。我必须在阵列上工作。我怎样才能改善这个?

更新:我想获得avg最小的切片的第一个元素的索引。

    public static void main(String[] args) {
    int[] A = new int[10000] ;
    double randomNum ;
    for(int i= 0 ; i<A.length ; i++)
    {
        randomNum = 0 + (double)(Math.random()*1); 
        if(randomNum>0.5)
            A[i]=-1;
        else
            A[i]=1;
    }

  System.out.println("Compute");   


    long start_time = System.nanoTime();
    int result = 0;
    double minavg = 100000 ;
    double avg;
    double suma = 0;
    int count = 0;

    for(int i=0 ; i<A.length-1 ; i++)
    {
        for(int k=i ; k<A.length ; k++)
        {
            suma+=A[k];
            count++;


            if(count>1)
            {
                 if(A[k]<A[k-1]) {
                avg=suma/count;
                if(minavg>avg)
                {
                    minavg=avg;
                    result =  i;
                }
                 }
            }


        } 
        suma=0;
        count=0;

    }

    long end_time = System.nanoTime();
    double difference = (end_time - start_time)/1e9;
    System.out.println(difference);
}

3 个答案:

答案 0 :(得分:0)

我试着在javascript中查看它。我开始的平均时间为0.101,并通过这些小修改下降到0.076:

function main() {
    var A = new Array() ;
    var randomNum ;
    for(var i= 0 ; i<1000 ; i++)
    {
        randomNum = 0 + Math.random(); 
        if(randomNum>0.5)
            A[i]=-1;
        else
            A[i]=1;
    }

  console.log("Compute");   


    var start_time = new Date().getTime();;
    var result = 0;
    var minavg = 100000 ;

    for(var i=0 ; i<A.length-1 ; i++)
    {
        var suma= A[i];
        var count=1;
        for(var k=i+1 ; k<A.length ; k++)
        {
            suma+=A[k];
            count++;
            if(A[k]<A[k-1]) {
                var avg=suma/count;
                if(minavg>avg)
                {
                    minavg=avg;
                    result =  i;
                }
            }
        } 
     }

    var end_time = new Date().getTime();
    var difference = (end_time - start_time)*1e-3;

    console.log(difference);

}

main();

我的观点是限制数量或测试,并在最后一次分配局部变量,以便最大化CPU寄存器和上下文。在编译java版本上,你可能会得到比我更好的结果。

答案 1 :(得分:0)

您可以做的一件事是将suma的数据类型更改为int,但请记住在double计算中将其强制转换回avg。这将避免增量中的大量数据类型转换,在我的情况下,它花费时间减少大约1/7。

其次,我不确定这个条件:

if (A[k] < A[k - 1]) 

Imho它应该是这样的(它花费时间减少1/2):

if (A[k] < minavg)

但我不确定最终结果是否正确,但它修复了@Crferreira提到的问题


我仍然不确定您的原始算法和任务。这是我的重写。平均而言,它需要时间进一步降低到最后一次测量的1/3

private static void calculateB(int[] A) {
    if (A == null || A.length < 2) {
        return;
    }
    long start_time = System.nanoTime();
    int result = 0;
    double minavg = 100000;
    double avg;
    int suma = A[A.length - 1];
    int count = 1;

    for (int i = A.length - 2; i >= 0; i--) {
        count += 1;
        int previous = A[i];
        suma += previous;

        if (previous < minavg) {
            avg = (double) suma / count;
            if (minavg > avg) {
                minavg = avg;
                result = i;
            }
        }
    }

    long end_time = System.nanoTime();
    double difference = (end_time - start_time) / 1e6;
    System.out.println(result + " " + minavg + " " + difference);
}

但是这个结果与原始结果不同,你必须检查它是否有效。我确实手动进行了计算,似乎没问题。这一个,从最后迭代表。多亏了这一点,我们有了一个sum的基础,我们可以在进一步的迭代中重用它。

至于一般规则 - 我不确定你在计算什么 - 从代码中看,它看起来像是具有最低平均值的项目的索引,包括索引上的那个 - 这是正确的吗?

答案 2 :(得分:0)

一项优化是删除计数&gt;通过重新排列代码来进行1次测试

for(int i=0 ; i<A.length-1 ; i++) {
    suma=A[i];
    for(int k=i+1 ; k<A.length ; k++) {
        suma+=A[k];
        count++;
        if(A[k]<A[k-1]) {