簡體   English   中英

Java優化,是否可以從hashMap獲得?

[英]Java optimization, gain from hashMap?

我已經給出了一些可愛的 Java代碼,其中包含很多類似的內容(一個循環執行約150萬次)。

code = getCode();
for (int intCount = 1; intCount < vA.size() + 1; intCount++)
{
   oA = (A)vA.elementAt(intCount - 1);
   if (oA.code.trim().equals(code))
       currentName= oA.name;
}

從切換到以下內容后,我是否會看到速度顯着提高

code = getCode();
//AMap is a HashMap
strCurrentAAbbreviation = (String)AMap.get(code);

編輯:VA的大小約為50.裝飾甚至不應該是必要的,但肯定會是不錯的調用50倍,而不是50 * 150萬。 vA中的項目是唯一的。

編輯:在幾個響應者的建議下,我對其進行了測試。 結果在底部。 多謝你們。

只有一種找出方法。

好吧,好吧,我測試了一下。

結果說明如下:

循環:18391ms散列:218ms

循環:18735ms哈希:234ms

循環:18359ms哈希:219ms

我想我會重構一下..

框架:

public class OptimizationTest {
    private static Random r = new Random();
    public static void main(String[] args){
        final long loopCount = 1000000;
        final int listSize = 55;

        long loopTime = TestByLoop(loopCount, listSize);
        long hashTime = TestByHash(loopCount, listSize);
        System.out.println("Looping: " + loopTime + "ms");
        System.out.println("Hash: " + hashTime + "ms");
    }

    public static long TestByLoop(long loopCount, int listSize){
        Vector vA = buildVector(listSize);
        A oA;

        StopWatch sw = new StopWatch();
        sw.start();
        for (long i = 0; i< loopCount; i++){
            String strCurrentStateAbbreviation;
            int j = r.nextInt(listSize);
            for (int intCount = 1; intCount < vA.size() + 1; intCount++){
                oA = (A)vA.elementAt(intCount - 1);
                if (oA.code.trim().equals(String.valueOf(j)))
                    strCurrentStateAbbreviation = oA.value;
            }
        }
        sw.stop();
        return sw.getElapsedTime();
    }

    public static long TestByHash(long loopCount, int listSize){
        HashMap hm = getMap(listSize);
        StopWatch sw = new StopWatch();
        sw.start();
        String strCurrentStateAbbreviation;
        for (long i = 0; i < loopCount; i++){
            int j = r.nextInt(listSize);
            strCurrentStateAbbreviation = (String)hm.get(j);
        }
        sw.stop();
        return sw.getElapsedTime();
    }

    private static HashMap getMap(int listSize) {
        HashMap hm = new HashMap();
        for (int i = 0; i < listSize; i++){
            String code = String.valueOf(i);
            String value = getRandomString(2);
            hm.put(code, value);
        }
        return hm;
    }

    public static Vector buildVector(long listSize) 
    {
        Vector v = new Vector();
        for (int i = 0; i < listSize; i++){
            A a = new A();
            a.code = String.valueOf(i);
            a.value = getRandomString(2);
            v.add(a);
        }
        return v;
    }

    public static String getRandomString(int length){
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i< length; i++){
            sb.append(getChar());
        }
        return sb.toString();
    }

    public static char getChar()
    {
        final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int i = r.nextInt(alphabet.length());
        return alphabet.charAt(i);
    }
}

嗯,是的,您很有可能會。 如果您具有良好的哈希碼,則從HashMap檢索將是恆定時間。

但是,您真正要找出的唯一方法就是嘗試一下。

這取決於您的地圖有多大,以及hashCode實現的良好程度(這樣您就不會有大腸菌病)。

您實際上應該進行一些實際的分析,以確保是否需要進行任何修改,因為您可能最終會花費時間來修復未損壞的問題。

在我看來,真正要比elementAt調用突出的是每次迭代所進行的字符串修剪。 我的直覺告訴我,這可能是一個更大的瓶頸,但只有剖析才能真正看出來。

祝好運

我會說是的,因為以上內容似乎是對vA.size()的線性搜索。 VA多大?

為什么不使用類似YourKit之類的東西(或插入另一個探查器)來查看循環這部分的成本。

使用Map當然是一項改進,有助於以后維護該代碼。

是否可以使用地圖取決於(vector?)是否包含唯一代碼。 給定的for循環會記住給定代碼的列表中的最后一個對象,這意味着哈希不是解決方案。

對於較小(穩定)的列表大小,僅將列表轉換為對象數組即可在提高可讀性的基礎上提高性能。

如果以上條件均不成立,請至少使用itarator檢查列表,以提高可讀性並提高性能。

要看。 你有多少內存?

我想速度要快得多,但是要對其進行分析。

我認為這里的主要因素是vA有多大,因為循環需要運行n次,其中n是vA的大小。 有了地圖,無論vA有多大,都沒有循環。 因此,如果n小,則改善將很小。 如果規模巨大,那么改善將是巨大的。 這是特別正確的,因為即使找到匹配的元素,循環仍然繼續! 因此,如果您在200萬個元素列表的元素1中找到匹配項,則仍然需要檢查最后1,999,999個元素!

是的,幾乎可以肯定會更快。 假設您的vA內容可以很好地散列,則平均循環25次(遍歷50次)要比散列圖查找慢。

但是,說到vA內容 ,將它們插入aMap時必須修剪它們,因為aMap.get(“ somekey”)不會找到鍵為“ somekey”的條目。

實際上,即使您不切換到哈希圖解決方案,也應該在插入vA時這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM