Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Измерение скорости работы методов, Предлагается специальный подход 
:(
    Опции темы
Mirkes
Дата 16.1.2012, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 7
Всего: 17



Не знаю, насколько это интересно, но разбираясь с темой Стандартные календарные расчеты столкнулся с тем, что мерять скорость можно очень по разному. В ходе обсуждения была дана ссылка на статью с JavaOne. Связавшись с автором статьи удалось выяснить основные принципы оценки скорости работы методов. На основе этого был разработан следующий класс Tester, позволяющий тестировать фактически любые методы.
Предлагаю обсудить необходимость такого стандарта для сравнений, поскольку вопрос о том, что быстрее возникает достаточно часто.

Итак код тестирующего класса
Код

/**
* Class to calculate speed evaluation of method
*
*/

import java.util.Calendar;

import tests.Days;


/**
 * Class to calculate speed evaluation of method
 *
 */

public class Tester {

    /**
    * main serves to start work
    * work method manage all works and mustn't override
    * All individual options is customize in methods
    * init - to init variables that nedded to tested method
    * test - to call parameters
    */

    /**
     * statist is equal to number of tests.
     * Method test() is called three times to heating
     * student must contain Student coefficient for statist and needed probability
     * testTime - times to test in miles
     */
    private static final int statist = 100;
    private static final double student = 2.6259;
    private static final int testTime = 1000;
    private static volatile boolean terminated = false;


    public static void main(String[] arg) {
        new Tester().work();
    }

    Runnable control = new Runnable() {
        public void run() {
            try {
                Thread.currentThread().sleep(testTime);
            } catch (InterruptedException e) {
                System.out.println("Error when try to sleep");
            }
            terminated = true;
        }
    };

    /**
     * work is main method managed all works
     */

    public void work() {
        init();
        int i;
        double val, val2, curr;
        // heating up
        val = 0;
        for (i = 0; i < 3; i++) {
            val += test();
        }
        System.out.println("Heating: " + (val / 3));
        // main testing loop
        val = 0;
        val2 = 0;
        for (i = 0; i < statist; i++) {
            curr = test();
            val += curr;
            val2 += curr * curr;
        }
        val = val / statist;
        val2 = Math.sqrt((val2 / statist - val * val) / (statist - 1)) * student;
        System.out.println("Mean " + val + " Mean error " + val2);


    }

    /**
     *  test method must call tested method
     *  You must change name of method.
     *  IMPORTANT method must return some value as return value or in parameters
     *  Result value must added to some counter or other value to print
     *  You mustn't change all lines? which marked as const in commentary.
     */

    public double test() {
        int count = 0; //const
        long time1 = System.nanoTime(); //const
        long sum = 0; // for you summs
        double ops; //const
        Thread th = new Thread(control);
        terminated = false;
        th.start();
        while (!terminated) { //const
            Days.joda(past, today, rob); // to call you method
            sum += rob[0] + rob[1] + rob[2]; // to sum method result
            count++; //const
        }
        long time2 = System.nanoTime(); //const
        ops = ((double)count) * 1000000 / (time2 - time1); //const
        System.out.println("ops/msec "+ops+"  empty "+sum); // to print you summs
        return ops; //const
    }


    /**
     * Place to variables, needed to tested method.
     */
    Calendar past;
    Calendar today;
    int rob[] = new int[3];


    /**
     * init serves to initialize variables to tested method
     */
    public void init() {
        past = Calendar.getInstance();
        past.set(2008, Calendar.AUGUST, 31); // 2008-08-30
        today = Calendar.getInstance(); // today
        today.set(2012, Calendar.MARCH, 1);
    }

}


Очевидно, что все, связанное с классом Days, приведено только для примера. Это подлежит замене.
Запуск из консоли с параметрами 
Код

 -server -Xmx1g -Xms1g -XX:+UseParallelOldGC

Это рекомендация автора статьи с JavaOne Алексея Шепилева.

Выходные данные:
Среднее число вызовов метода за милисеккунду и оценка ошибки по критерю Стьюдента.
Быстрее тот метод, у которого показатель БОЛЬШЕ.



Это сообщение отредактировал(а) Mirkes - 17.1.2012, 03:22


--------------------
Mirkes
PM MAIL   Вверх
Stolzen
Дата 16.1.2012, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1041
Регистрация: 17.10.2005

Репутация: 23
Всего: 48



Неплохо, думаю, найдет применение. А для самих замеров можно использовать StopWatch из Commons Lang.
А кстати, почему nanoTime? 


--------------------
datatalks.ru - анализ данных, статистика, машинное обучение
PM MAIL WWW   Вверх
Mirkes
Дата 16.1.2012, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 7
Всего: 17



Цитата(Stolzen @  16.1.2012,  19:34 Найти цитируемый пост)
А кстати, почему nanoTime?

Просто насколько я знаю это самый точный метод получения времени. Я понимаю, что он зависит от платформы. 
Давайте решим, что следует использовать и поставим вместо nanoTime.


--------------------
Mirkes
PM MAIL   Вверх
Stolzen
Дата 16.1.2012, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1041
Регистрация: 17.10.2005

Репутация: 23
Всего: 48



А что Алексей Шепилев может подсказать по этому поводу?


--------------------
datatalks.ru - анализ данных, статистика, машинное обучение
PM MAIL WWW   Вверх
Samotnik
Дата 16.1.2012, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Super star !
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 7192
Регистрация: 4.11.2006
Где: Минск City

Репутация: 8
Всего: 191



кстати, народ, хотел создать такую же тему.
Какие есть способы измерения производительности? 
Естественно, ищу способы, кроме System.currentTimeMillis() в начале и конце метода.  smile 
PM MAIL   Вверх
Mirkes
Дата 17.1.2012, 03:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 7
Всего: 17



Предложенный вариант основан как раз на подсказках Шепилева. В том числе и nanoTime. Он пишет, что они планируют опубликовать свой измеритель, но пока он не опубликован.


--------------------
Mirkes
PM MAIL   Вверх
jk1
Дата 17.1.2012, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

позволяющий тестировать фактически любые методы.


Я не уверен, что приведенный код способен гарантировать Jit-компиляцию (для чего собственно разогрев и делается). Кроме того, неплохо бы жестко зафиксировать режим JVM, client или server, там же есть сильные различия в том числе в ряде агрессивных оптимизаций.
NanoTime на многих платформах бесполезно, они даже милисекундной точности толком дать не могут, тот же WinXP тому примером.

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


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Mirkes
Дата 17.1.2012, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 586
Регистрация: 18.8.2011
Где: Красноярск

Репутация: 7
Всего: 17



Цитата(jk1 @  17.1.2012,  11:18 Найти цитируемый пост)
Я не уверен, что приведенный код способен гарантировать Jit-компиляцию (для чего собственно разогрев и делается). Кроме того, неплохо бы жестко зафиксировать режим JVM, client или server, там же есть сильные различия в том числе в ряде агрессивных оптимизаций.NanoTime на многих платформах бесполезно, они даже милисекундной точности толком дать не могут, тот же WinXP тому примером.


В соответсвии с рекомендациями Шепелева (правда он их писал для конкретной задачи и не утверждал их оптимальности) я указал параметры запуска:
Цитата(Mirkes @  16.1.2012,  18:32 Найти цитируемый пост)
Запуск из консоли с параметрами код Java1: -server -Xmx1g -Xms1g -XX:+UseParallelOldGChighlightSyntax('java_5YzE','java');Это рекомендация автора статьи с JavaOne Алексея Шепилева.


То, что этот измеритель не заменяет профайлер - очевидно.


--------------------
Mirkes
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0771 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.