Если нельзя, но очень хочется, то нужно обязательно и ничего в мире не стоит того, чтобы делать из этого проблему!


Интересна Java? Кликай по ссылке и изучай!
Если тебе полезно что-то из того, чем я делюсь в своем блоге - можешь поделиться своими деньгами со мной.
с пожеланием
столько времени читатели провели на блоге - 
сейчас онлайн - 

четверг, 23 октября 2014 г.

Бесплатный java профайлинг

Можно качнуть какую-то тулу, а можно и подручными средствами. Я тут оптимизировал для субботней игры алгоритм, один за другим расширяя боттлнеки. И пользовался всего 3 методами.

Подсчитать, сколько времени выполняется блок кода 
public void someMethod() {
    long time = Calendar.getInstance().getTime().getTime();
    // ... some code ...           
    System.out.println(Calendar.getInstance().getTime().getTime() - time + "ms");
}
Подсчитать сколько раз выполняется метод
public static long count = 0;

public void someMethod() {
    if (count++ % 10000 == 0) System.out.print("+");
    // ... some code ...
}
Подсчитать, кто сколько раз (в каком контексте) вызывал этот метод
public static Map<String, Integer> count = new HashMap<String, Integer>();

public void someMethod() {
    Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
    for (StackTraceElement[] list : traces.values()) {
        if (list.length == 0) continue;
        boolean mine = list[0].getMethodName().equals("dumpThreads");
        if (!mine) continue;
        StringBuilder builder = new StringBuilder();
        for (StackTraceElement el : list) {
            if (el.getFileName().equals("Thread.java")) continue;
            builder.append(el.getClassName()).append(".")
                    .append(el.getMethodName()).append("():")
                    .append(el.getLineNumber()).append("\n");
        }
        String id = builder.toString() ;
        int n = 0;
        if (count.containsKey(id)) {
            n = count.get(id) + 1;
        }
        count.put(id, n);
    }
    if (count.size() % 10000 == 0) System.out.println(count.toString());
 
    // ... some code ...
}
Тут константа 10000 подбирается вручную, в зависимости от общего количество вызовов в секунду. У меня их очень дофига.
Пользуясь этими тремя методами я увеличил производительность в 300 раз. По хорошему их бы в класс отдельный выделить и повторно использовать. Но то уже потом как-то...

4 комментария:

  1. Саша, отличный подход) Я сам часто это использую, и результаты интересные получаются (когда надо именно перформанс методов замерять, то это вполне может быть оптимальным решением)

    А насчёт качать - в принципе качать где-то с Java6 начиная можно и не качать) В JDK встроен профайлер jvisualvm.exe http://docs.oracle.com/javase/7/docs/technotes/guides/visualvm/

    А из платных (с триалом) лучшее что я когда-либо видел (очень крут) - YourKit Java Profiler http://yourkit.com/

    Профайлеры (особенно последний) крут когда надо исследовать куда девается память) Или что-то с потоками хитрое

    ОтветитьУдалить
    Ответы
    1. Лёня спасибо!
      YourKit Java Profiler, юзал пару раз. больше совесть не позволяет. Надо покупать, но пока не надо :)
      jvisualvm.exe тоже юзаю.
      Спасибо за заметки!

      Удалить
  2. Привет! : )
    Во втором, примере возможно оЧеПятка, а именно:
    переменная count должна именоваться counter ?

    ОтветитьУдалить