【问题标题】:Java compilation optimization and performanceJava编译优化和性能
【发布时间】:2015-08-18 17:38:04
【问题描述】:
 public static void main(String[] args) {
     double [] boxes;
        boxes = new double[]  {20, 10, 5, 40, 20, 41, 41, 2, 6, 7, 3, 4, 5, 6, 23, 34, 7, 8, 2, 2};
        double heaviest = 0;
        double normal = 0;
        double heavy = 0;
        double totalCost;
        double a = 0;
        double b = 0;
        int repeatCount=0;

        for (int i = 1; i < boxes.length; i++) {
            if (boxes[i] > heaviest)
                heaviest = boxes[i];
        }

        for(double element: boxes) {
            if(element==heaviest) {
                repeatCount = repeatCount+1;
            }
        }

        System.out.println("Count :" +repeatCount);

        for (int j =0; j<boxes.length; j++) {
            if (boxes[j] < heaviest) {
                a = boxes[j] * 2;
                normal = normal+a;
            } else {
                b =  (boxes[j] * 3.5);
                heavy = heavy+b;
            }
        }
        totalCost = normal+heavy;
        System.out.println("total cost of the insuranse is  "+ totalCost);
    }

第 1 部分:我需要将最大的元素乘以 3.5,然后再乘以 2,然后将其相加得到总数。

第 2 部分:我还想要最大元素的出现次数。 我们也可以将最大的元素存储在另一个数组中。

在我的代码中,我已经完成了第 1 部分,对于第 2 部分,我正在计算最大元素的出现次数。

我的问题:

如果有超过1000 个元素,是否有其他方法可以减少编译时间或优化代码?

我还尝试通过将数组转换为列表来使用Collections.frequency(myArray, largestElement)

【问题讨论】:

  • 当您从数组中获取最大元素时,您可以尝试按降序对数组进行排序。所以你会得到第一个元素来执行你所说的任务。

标签: java arrays compiler-optimization


【解决方案1】:

一如既往,正确性比性能更重要。

不知道为什么它在寻找最重的框时会忽略第一个框。

您可以减少代码,但最大的问题是您的代码运行时间不够长,无法被 JIT 编译。即便如此,与 Java 的启动成本相比,它还是微不足道的。

简而言之,除非您的程序持续几百毫秒,否则我不会担心性能。

顺便说一句,您可以使用单个循环来缩短代码,但就像我说的那样,在这种情况下不会有太大区别。

我可能会这样写。

double[] boxes = {20, 10, 5, 40, 20, 41, 41, 2, 6, 7, 3, 4, 5, 6, 23, 34, 7, 8, 2, 2};
double heaviest = -1;
int count = 0;
double sum = 0;
for (double box : boxes) {
    sum += box;
    if (box > heaviest) {
        count = 1;
        heaviest = box;
    } else if (box == heaviest) {
        count++;
    }
}

// double total = sum * 2 - heaviest * count * 2 + heaviest * count * 3.5;
double total = sum * 2 + heaviest * count * 1.5;
System.out.println("total: " + total);

注意:只有一个循环。您可以随时计算计数和总和。

【讨论】:

  • “一如既往,正确性比性能更重要。” ...你确定“总是”吗?
  • @Jean-FrançoisSavard 您想要一个错误但非常快的系统,还是一个正确但足够快的系统。注意:我认为一个速度不够快的系统是不正确的,这是我的;)也有例外,例如轻量级性能监视器,无论如何这只是一个估计。
  • 有道理,“正确性”起初并没有出现在我的脑海中。 +1。
  • 不要忘记,减少代码并避免迭代或 for 循环本身就是一个很大的性能提升。我自己打算在一个 for 循环中发布一个类似的代码,并注意到你已经做了同样的事情。当您已经知道数据的方向时,总有机会避免额外的代码。
  • 请定义你所说的“工作”是什么意思......我不知道你的程序是否打算每天打印一次或者这种行为是否不正确;)......更严重的是,它确实如此它应该是什么,只是以非常缓慢的方式。我们可以肯定地说该程序已损坏,但考虑到它执行相同的功能,我们真的可以将问题归类为“功能”问题吗?
【解决方案2】:
public static void main(String[] args) {
    double [] boxes = new double[]  {20, 10, 5, 40, 20, 41, 41, 2, 6, 7, 3, 4, 5, 6, 23, 34, 7, 8, 2, 2};
    double heaviest = 0;
    double normal = 0;
    double heavy = 0;
    double totalCost;
    int repeatCount=0;

    for (double d : boxes) {
        heaviest = Math.max (boxes[i], heaviest);
    }

    for (double d : boxes) {
        if(d == heaviest) {
            repeatCount++;
        }
    }
    System.out.println("Count: " + repeatCount);

    for (double d : boxes) {
        if (d == heaviest) {
            heavy += d * 2.0;       
        } else {
            heavy += d * 3.5;
        }
    }
    totalCost = normal+heavy;

    System.out.println("Total cost of the insuranse is: " + totalCost);
}

根据您的知识,这是在遵循您的代码,但修正了一点。您永远不需要使用i,也不需要将结果存储在ab,而是可以使用+= 运算符。

话虽如此,double d1 == double d2 使用起来很危险。我不建议直接使用它们。阅读this 文章或this。实际上,我建议您同时阅读。

【讨论】:

  • 你已经发现所有的循环都有相同的形式,试着看看你是否可以只使用一个循环(不看 mu 答案;)
  • 是的,他们可以根据您的回答,但是我不想过度修改代码,该回答比 StackOverflow 更适合 CodeReview。
猜你喜欢
  • 2011-08-24
  • 1970-01-01
  • 2012-12-19
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多