【问题标题】:How to optimize the code any further?如何进一步优化代码?
【发布时间】:2015-09-27 15:28:56
【问题描述】:

对你们所有人来说都是美好的一天。

我的代码可以在几秒钟内完成 Excel Pivot 的工作。然而,我的代码在不少于 30 分钟内完成了同样的事情。我对这种差异感到震惊!我很确定我可以优化我的代码,使其比现在快得多。任何帮助将不胜感激。

请快速查看代码。如有必要,我将详细解释它究竟做了什么。谢谢!

public void countImages(ArrayList<String> all) throws IOException {
        HashSet<String> uStrings = new HashSet<>();
        int Counter = 0;
        int C500x500 = 0;
        int C800x800 = 0;
        int C1000x1000 = 0;
        int G1000x1000 = 0;
        write("Vendor ID, Count of Images, Less than 500 x 500, Less than 800 x 800, Less than 1000 x 1000, Greater than 1000 x 1000", "ImageCount_Data");
        for (String single : all) {
            String[] linearray = single.split(",");
            uStrings.add(linearray[0]);
        }
        totallines = uStrings.size();
        completedlines = 0;
        percentage = 0;
        setPercent(0);
        for (String uString : uStrings) {
            Counter = 0;
            C500x500 = 0;
            C800x800 = 0;
            C1000x1000 = 0;
            G1000x1000 = 0;
            for (String single : all) {
                String[] linearray = single.split(",");
                if (linearray[0].equals(uString)) Counter++;
                if ((linearray[1].equals("Less than 500 x 500")) && linearray[0].equals(uString)) C500x500++;
                if ((linearray[1].equals("Less than 800 x 800")) && linearray[0].equals(uString)) C800x800++;
                if ((linearray[1].equals("Less than 1000 x 1000")) && linearray[0].equals(uString)) C1000x1000++;
                if ((linearray[1].equals("Greater than 1000 x 1000")) && linearray[0].equals(uString)) G1000x1000++;
            } //END OF 2ND FOR LOOP
            write(uString + "," + Counter + "," + C500x500 + "," + C800x800 + "," + C1000x1000 + "," + G1000x1000, "ImageCount_Data");
            completedlines++;
            percentage = (completedlines / totallines) * 100;
            setPercent(Math.round(percentage));
            Icwindow.frame.setTitle("Writing Image Count Data: " + getPercent() + "%");
        } //END OF 1ST FOR LOOP
        Icwindow.frame.setTitle("Process Cloudinary ImageCount Data");
    }

【问题讨论】:

  • 你有三个循环,我相信你可以只用一个。

标签: java optimization arraylist hashset


【解决方案1】:

您正在迭代第 0 列中所有可能的字符串,然后在该循​​环中再次迭代所有字符串。因此,您的算法是 O(n²),而 Excel 采用了更快(可能是 O(n) 摊销)算法。

您可以使用 HashMap&lt;String, Counts&gt; 来跟踪计数,只使用一个 for 循环而不是两个嵌套循环。

Counts 对象将包含您的类的计数,如下所示:

class Counts {
    int c500;
    int c800;
    int c1000;
    int cOther;

    void count(String s) {
        switch(s) {
        case "Less than 500 x 500": c500++; break;
        case "Less than 500 x 500": c800++; break;
        case "Less than 500 x 500": c1000++; break;
        case "Greater than 1000 x 1000": cOther++; break;
        default: throw new AssertionError();
        }
    }
}

另一个提示:你可以通过添加c500 + c800 + c1000 + cOther来获取全局计数器。

【讨论】:

  • 谢谢lllogiq!有人确实告诉我,上次我在做一个类似的程序,但我并没有真正明白,我是怎么做的。你能帮我写一个简短的示例代码吗?
  • 我想,我明白了。所以这将解决我的计数问题一次。但是,我正在计算 3 个不同字符串的重复次数。如何在一个循环中实现这一目标?
  • 我在答案中添加了一个示例 sn-p。
【解决方案2】:

非常感谢!

下面是我使用 Hash Map 的新代码,它确实比我以前的代码快得多。但是,代码中似乎有一些不正确的地方,因为计数仅对第一个 Hash Map 是正确的,而其余 4 Has Maps 的计数不正确。我可以请您看一下并告诉我您是否发现新代码中有任何奇怪之处?

编辑 - 我错过了在 switch case 语句中添加中断!这完美而快速! :D

public void countImages(ArrayList<String> all) throws IOException {
        HashMap<String, Integer> counter = new HashMap<>();
        HashMap<String, Integer> c500 = new HashMap<>();
        HashMap<String, Integer> c800 = new HashMap<>();
        HashMap<String, Integer> c1000 = new HashMap<>();
        HashMap<String, Integer> g1000 = new HashMap<>();

        write("Vendor ID, Count of Images, Less than 500 x 500, Less than 800 x 800, Less than 1000 x 1000, Greater than 1000 x 1000", "ImageCount_Data");

        for (String single : all) {
            String[] linearray = single.split(",");
            if (!counter.containsKey(linearray[0])) {
                counter.put(linearray[0], 1);
            } else {
                counter.put(linearray[0], counter.get(linearray[0]) + 1);
            }

            switch (linearray[1]) {

            case "Less than 500 x 500" :
                if (!c500.containsKey(linearray[0])) {
                    c500.put(linearray[0], 1);
                } else {
                    c500.put(linearray[0], c500.get(linearray[0]) + 1);
                }
            case "Less than 800 x 800" :
                if (!c800.containsKey(linearray[0])) {
                    c800.put(linearray[0], 1);
                } else {
                    c800.put(linearray[0], c800.get(linearray[0]) + 1);
                }
            case "Less than 1000 x 1000":
                if (!c1000.containsKey(linearray[0])) {
                    c1000.put(linearray[0], 1);
                } else {
                    c1000.put(linearray[0], c1000.get(linearray[0]) + 1);
                }
            case "Greater than 1000 x 1000" :
                if (!g1000.containsKey(linearray[0])) {
                    g1000.put(linearray[0], 1);
                } else {
                    g1000.put(linearray[0], g1000.get(linearray[0]) + 1);
                }
            }
        }

        for (String key : counter.keySet()) {
            write(key + "," + counter.get(key) + "," + c500.get(key) + "," + c800.get(key) + "," + c1000.get(key) + "," + g1000.get(key), "ImageCount_Data");
        }

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多