Неправильное время выполнения метода - PullRequest
0 голосов
/ 19 декабря 2011

Я хочу проверить время добавления и получения элемента в простой и универсальной хэш-карте:

public void TestHashGeneric(){


        Map hashsimple = new HashMap();             

        long startTime = System.currentTimeMillis();



        for (int i = 0; i < 100000; i++) {
            hashsimple.put("key"+i, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
        }

        for (int i = 0; i < 100000; i++) {
            String ret =(String)hashsimple.get("key"+i);
        }
        long endTime =System.currentTimeMillis();

        System.out.println("Hash Time " + (endTime - startTime) + " millisec");

        Map<String,String> hm = new HashMap<String,String>();

        startTime =  System.currentTimeMillis();



        for (int i = 0; i < 100000; i++) {
            hm.put("key"+i, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" );
        }

        for (int i = 0; i < 100000; i++) {
            String ret = hm.get("key"+i);
        }
        endTime = System.currentTimeMillis();

        System.out.println("Hash generic Time " + (endTime - startTime) + " millisec");         

    }

Проблема в том, что я получаю другое время, если меняю места между разделами кода hashmap! если я помещу циклы (с указанием времени печати) универсального ниже простого, я получаю лучшее время для общего, и если я помещаю простой ниже универсального, я получаю лучшее время для простого!

То же самое происходит, если я использую разные методы для этого.

Ответы [ 4 ]

1 голос
/ 19 декабря 2011

Если у вас есть один цикл, который достигает порога компиляции (около 10 КБ), весь метод компилируется. Это может сделать либо первый цикл более быстрым (так как он оптимизирован правильно, так как второй цикл не имеет информации о счетчике), либо второй цикл (после его компиляции до его запуска)

Этот самый простой способ исправить это - поместить каждый тест в свой метод, и они будут независимо скомпилированы и оптимизированы. (Порядок может иметь значение, но он не так важен). Я бы по-прежнему предлагал провести тест несколько раз, чтобы увидеть, как меняются результаты.

1 голос
/ 19 декабря 2011

JIT будет компилировать и оптимизировать вашу программу во время ее работы, поэтому 2-й запуск всегда будет быстрее.

Вам следует внести следующие изменения:

  1. Сначала запустите оба теста без привязки, а затем повторно запустите их по времени, чтобы JIT не повлиял на вас.
  2. Вам следует использовать System.nanoTime(), поскольку это более точнодля синхронизации (вы никогда не должны получать разность 0).
  3. Вы также должны проверить некоторые пустые методы, так как вы также синхронизируете операцию конкатенации строк в каждом цикле.

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

0 голосов
/ 19 декабря 2011

Это неправильный способ выполнения микропроцессоров, так как он очень сложный ( Почему? ).Я предлагаю вам использовать Caliper framework для этого.

0 голосов
/ 19 декабря 2011

Java Runtime довольно сложен - он немного изучает / оптимизирует во время работы. Вы можете получить желаемый тест, предварительно "прогрев" JVM. Попробуйте дважды позвонить TestHashGeneric() и посмотрите, что даст второй набор результатов.

У вас также есть вдвое больше памяти в памяти при втором запуске. Существует множество переменных, которые могут повлиять на этот тест.

...