Оптимизация Java, выгода от hashMap? - PullRequest
1 голос
/ 30 октября 2009

Мне дали немного прекрасного Java-кода, который имеет много подобных вещей (в цикле, который выполняется около 1,5 миллионов раз).

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 * 1,5 миллиона. , Предметы в ВА уникальны.

Редактировать: По предложению нескольких респондентов я проверил его. Результаты внизу. Спасибо, ребята.

Ответы [ 11 ]

11 голосов
/ 30 октября 2009

Есть только один способ узнать.

8 голосов
/ 30 октября 2009

Хорошо, хорошо, я проверял это.

Результаты следуют для вашего просветления:

Цикл: 18391мс Хэш: 218 мс

Цикл: 18735мс Хэш: 234 мс

Цикл: 18359мс Хеш: 219мс

Я думаю, что я буду рефакторинг этого бита ..

Каркас:

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);
    }
}
3 голосов
/ 30 октября 2009

Эх, есть хороший шанс, что вы бы, да. Извлечение из HashMap будет постоянным временем, если у вас есть хорошие хэш-коды.

Но единственный способ узнать это - попробовать.

2 голосов
/ 30 октября 2009

Вы должны действительно провести реальное профилирование, чтобы быть уверенным, что какие-либо изменения необходимы, так как вы можете потратить свое время на исправление чего-то, что не сломано.

Что на самом деле выделяет меня чуть больше, чем вызов elementAt, так это обрезка строк, которую вы выполняете на каждой итерации. Моя интуиция говорит мне, что это может быть большим узким местом, но только профилирование может сказать.

Удачи

2 голосов
/ 30 октября 2009

Это зависит от того, насколько велика ваша карта и насколько хороша ваша реализация hashCode (чтобы у вас не было коллизий).

1 голос
/ 30 октября 2009

Зависит. Сколько памяти у тебя есть?

Я бы догадался намного быстрее, но профилируйте его.

1 голос
/ 30 октября 2009

Использование карты, безусловно, будет улучшением, которое поможет поддерживать этот код в дальнейшем.

Возможность использования карты зависит от того, содержит (вектор?) Уникальные коды или нет. Данный цикл for запомнил бы последний объект в списке с заданным кодом, что означало бы, что хеш не является решением.

Для небольших (стабильных) размеров списков простое преобразование списка в массив объектов показало бы повышение производительности в дополнение к некоторой лучшей читаемости.

Если ничего из вышеперечисленного не выполняется, по крайней мере, используйте итератор для проверки списка, обеспечивая лучшую читаемость и некоторое (вероятное) повышение производительности.

1 голос
/ 30 октября 2009

Почему бы вам не использовать что-то вроде YourKit (или вставить другой профилировщик), чтобы увидеть, насколько дорогая эта часть цикла.

1 голос
/ 30 октября 2009

Я бы сказал, да, так как вышеприведенное выглядит как линейный поиск по vA.size (). Насколько большой ва?

0 голосов
/ 30 октября 2009

Да, это почти наверняка будет быстрее. Зацикливание в среднем 25 раз (на полпути через ваши 50) медленнее, чем поиск по хэш-карте, предполагая, что ваше содержимое vA прилично хэшируется.

Однако, говоря о вашем контенте vA , вам придется обрезать их при вставке в aMap, потому что aMap.get ("somekey") не найдет запись с ключом " Somekey ".

На самом деле, вы должны делать это при вставке в vA, даже если вы не переключаетесь на решение hashmap.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...