面向大输入的Java优化算法和赋值运算符

面向大输入的Java优化算法和赋值运算符,java,algorithm,optimization,mathematical-optimization,Java,Algorithm,Optimization,Mathematical Optimization,我有一段代码,在时钟速度方面必须运行得非常快。该算法已在O(N)中。需要2秒,需要1秒。对于大多数A.length输入,大约100000次需要.3s,除非调用某一行代码的次数达到极限。(对于深奥的编程挑战) 它使用算术级数的计算,即1,2,…N->1,3,4,10,15。。 可以用n*(n+1)/2表示 我把这个等式循环了几十万次。 我无法访问输入,也无法显示它。我能得到的唯一信息是它运行的时间。 具体而言,方程式为: s+=(n+c)-((n*(n+1))/2); s和c的值可以在0到10亿

我有一段代码,在时钟速度方面必须运行得非常快。该算法已在O(N)中。需要2秒,需要1秒。对于大多数A.length输入,大约100000次需要.3s,除非调用某一行代码的次数达到极限。(对于深奥的编程挑战)

它使用算术级数的计算,即1,2,…N->1,3,4,10,15。。 可以用n*(n+1)/2表示 我把这个等式循环了几十万次。 我无法访问输入,也无法显示它。我能得到的唯一信息是它运行的时间。 具体而言,方程式为:

s+=(n+c)-((n*(n+1))/2);
s和c的值可以在0到10亿之间

n的范围为0到100000

就时钟速度而言,编写此语句最有效的方法是什么? 我听说除法比乘法需要更多的时间,但除此之外,我无法确定在一行还是多行作业中写这篇文章更有效。 除法和乘法,还是先乘后除? 创建自定义整数类型也会有很大帮助吗

按要求编辑,完整代码,输入大小写(如果很难看,很抱歉,我一直在剥离它):

publicstaticvoidmain(字符串[]args){
int A[]={3,4,8,5,1,4,6,8,7,2,2,4};//输出44
int K=6;
//长启动=System.currentTimeMillis();;
//对于(int i=0;i100000000)返回100000000;
返回s+c;
}

从挑战中返回:

检测到的时间复杂度:

O(N)

测试时间结果

范例 示例测试0.290秒。嗯

单身 单元素0.290s。嗯

双重的 两个元素0.290s。嗯

小函数 小型功能测试0.280秒。嗯

小随机 小随机序列长度=~100 0.300 s。嗯

小型随机2 小随机序列长度=~100 0.300 s。嗯

中随机 混沌介质序列长度=~3000 0.290 s。嗯

大范围 大范围测试,长度=~100000 2.200 s。超时错误 运行时间:>2.20秒,时限:1.02秒。

大随机数 随机大序列长度=~100000 0.310 s。嗯

大号回答 大回答测试0.320秒。嗯

大雪极端
所有最大值=~100000 0.340 s。好的

通过一点代数,您可以简单地将表达式
(n+c)-(n*(n+1))/2
转换为
c-((n*(n-1))/2)
以删除加法运算。然后您可以将除法替换为
2
,并将位向右移动
1
,这比除法更快。试着替换

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


如果(Math.abs(A[ml]-A[mxl])>1而不是x/2,我会尝试删除这一行
if

删除System.out.println()可以将速度提高1000倍。 但是要小心,否则你的整个算法会被虚拟机删除,因为你不使用它。 旧代码:

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

for(int i=0;i我将尝试以下操作,并在每次更改后分析代码,以检查速度是否有任何提高


替换:

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


替换

/2
ml++;
mxl=ml;


可能避免对同一元素的数组访问(java的内部边界检查可能需要一些时间)


因此,至少在局部变量中保留一个[i]

去掉for循环中的System.out.println())你会惊讶于你的计算速度会快得多。

我会先创建一个C版本,看看“直接访问金属”有多快。很可能,您正在尝试优化已优化到极限的计算。

嵌套赋值,即代替

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

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

有时发生在OpenJDK源代码中。它主要导致用
*dup
s替换
*load
字节码指令。根据我的实验,它确实提供了很小的加速,但它非常强大,我不建议手动编写这样的代码。

我没有权限验证所有输入。以及时间范围。但是是一个运行O(N)肯定。并已改善。运行,让我知道你的反馈。我会提供详细信息,如果必要的

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;
}
公共静态int解决方案(int[]A,int K){
int minIndex=0;
int maxIndex=0;
int end=A.长度;
int slize=结束;
int startIndex=0;
int-diff=0;
int minMaxIndexDiff=0;
对于(int currendex=1;currendexa[maxIndex]){
maxIndex=currIndex;
}else if(A[currendex]K){
minMaxIndexDiff=currendex-startIndex;
如果(minMaxIndexDiff>1){
slize+=((minMaxIndexDiff*(minMaxIndexDiff-1))>>1);
如果(差异>0){
slize=slize+(diff*minMaxIndexDiff);
}
}
如果(最小索引==当前索引){
差异=当前索引-(最大索引+1);
}否则{
差异=当前索引-(最小索引+1);
}
如果(冻结>100000000){
回报100000000;
}
minIndex=货币指数;
maxIndex=currIndex;
startIndex=货币指数;
}
}
如果((开始索引+1)=结束){
回程切片;
}
如果(冻结>100000000){
回报100000000;
}
minMaxIndexDiff=结束-开始索引;
如果(minMaxIndexDiff>1){
slize+=((minMaxIndexDiff*(minMaxIndexDiff-1))>>1);
如果(差异>0){
slize=slize+(diff*minMaxIndexDiff);
}
}
回程切片;
}

发布你的代码,然后我可以尝试改进它,因为你知道
n>0
你可以用
>1
替换
/2
。与此相比,其他一切都是微不足道的。对于真正的测量,使用预热:启动循环两次,第一次不测量时间。这给了JVM时间来正确编译你的方法。@SargeBorsch:是的,不是
>>1
ml++;
mxl=ml;
mxl=++ml;
t=i-ml;
s+=(t+c)-((t*(t+1))/(short)2);
i=ml;
ml++;
mxl=ml;
s+=((t=i-ml)+c);
s-=((t*(t+1))/(short)2);
i=ml;
mxl=++ml;
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;
}