Java Optimizing arithmetic and Assignment Operators for large input

天大地大妈咪最大 提交于 2019-12-06 13:21:27

I dont have access to validate all inputs. and time range. but this one runs O(N) for sure. and have improved. run and let me know your feedback.i will provide details if necessary

public static int solution(int[]A,int K){
    int minIndex=0;
    int maxIndex=0;
    int end=A.length;
    int slize = end;
    int startIndex = 0;
    int diff = 0;
    int minMaxIndexDiff = 0;
    for(int currIndex=1;currIndex<end;currIndex++){
        if(A[currIndex]>A[maxIndex]){
            maxIndex=currIndex;
        }else if(A[currIndex]<A[minIndex]){
            minIndex=currIndex;
        }
        if( (A[maxIndex]-A[minIndex]) >K){
            minMaxIndexDiff= currIndex- startIndex;
            if (minMaxIndexDiff > 1){
                slize+= ((minMaxIndexDiff*(minMaxIndexDiff-1)) >> 1);
                if (diff > 0 ) {
                    slize = slize + (diff * minMaxIndexDiff);
                }
            }

            if (minIndex == currIndex){
                diff = currIndex - (maxIndex + 1);
            }else{
                diff = currIndex - (minIndex + 1);
            }
            if (slize > 1000000000) {
                return 1000000000;
            }
            minIndex = currIndex;
            maxIndex = currIndex;
            startIndex = currIndex;
        }
    }
    if ( (startIndex +1) == end){
        return slize;
    }
    if (slize > 1000000000) {
        return 1000000000;
    }
    minMaxIndexDiff= end- startIndex;
    if (minMaxIndexDiff > 1){
        slize+= ((minMaxIndexDiff*(minMaxIndexDiff-1)) >> 1);
        if (diff > 0 ) {
            slize = slize + (diff * minMaxIndexDiff);
        }
    }

    return slize;
}

With a little algebra, you can simply the expression (n+c)-((n*(n+1))/2) to c-((n*(n-1))/2) to remove an addition operation. Then you can replace the division by 2 with a bit-shift to the right by 1, which is faster than division. Try replacing

s+=(n+c)-((n*(n+1))/2);

with

s+=c-((n*(n-1))>>1);

Get rid of the System.out.println() in the for loop :) you will be amazed how much faster your calculation will be

Nested assignments, i. e. instead of

t=i-ml;
s+=(t+c)-((t*(t+1))/(short)2);
i=ml;
ml++;
mxl=ml;

something like

s+=((t=i-ml)+c);
s-=((t*(t+1))/(short)2);
i=ml;
mxl=++ml;

sometimes occurs in OpenJDK sources. It mainly results in replacing *load bytecode instructions with *dups. According to my experiments, it really gives a very little speedup, but it is ultra hadrcore, I don't recommend to write such code manually.

I would try the following and profile the code after each change to check if there is any gain in speed.


replace:

if(Math.abs(A[ml]-A[mxl])<=K)

by

int diff = A[ml]-A[mxl];
if(diff<=K && diff>=-K)

replace

/2

by

>>1

replace

ml++;
mxl=ml;

by

mxl=++ml;

Maybe avoid array access of the same element (internal boundary checks of java may take some time)

So staore at least A[i] in a local varianble.

I would create a C version first and see, how fast it can go with "direct access to the metal". Chances are, you are trying to optimize calculation which is already optimized to the limit.

I would try to elimnate this line if(Math.abs(A[ml]-A[mxl])<= by a faster self calculated abs version, which is inlined, not a method call!

The cast to (short) does not help, but try the right shift operator X >>1 instead x / 2

removing the System.out.println() can speed up by factor of 1000. But be carefull otherwise your whole algorithm can be removed by the VM becasue you dont use it. Old code:

for(int i=0;i<100000;i++){
            System.out.println(mezmeriz4r(A,K));
}

New code:

int dummy = 0;
    for(int i=0;i<100000;i++){
          dummy =   mezmeriz4r(A,K);
    }
//Use dummy otherwise optimisation can remove  mezmeriz4r
System.out.print("finished: " + dummy);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!