当我运行这段代码时,我得到了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);
}
答案 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);
}
至于一般规则 - 我不确定你在计算什么 - 从代码中看,它看起来像是具有最低平均值的项目的索引,包括索引上的那个 - 这是正确的吗?
答案 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]) {