如何进一步优化代码?

时间:2015-07-09 10:08:19

标签: java optimization arraylist hashset

祝大家度过美好的一天。

我的代码可以完成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");
    }

2 个答案:

答案 0 :(得分:1)

您正在遍历列0中的所有可能字符串,然后在该循​​环内再次遍历所有字符串。因此,您的算法为O(n²),其中Excel可以通过更快(可能是O(n)摊销)的算法获得。

您可以使用HashMap<String, Counts>来跟踪计数,只使用一个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来获取全局计数器。

答案 1 :(得分:0)

非常感谢你!

下面是我使用Hash Map的新代码,它确实比我之前的代码快得多。但是,代码中似乎存在不正确的原因,因为计数仅对第一个哈希映射是正确的,其余4映射具有不正确的计数。我可以请你看看并告诉我你是否注意到新代码中有什么奇怪的东西?

编辑 - 我错过了在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");
        }

    }