►Работа с профайлером...339

We use cookies. Read the Privacy and Cookie Policy

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

_________________

339 стр. Глава 30. Десять основных возможностей Dev-C++

Однако если алгоритмические ресурсы исчерпаны, а программа работает слишком медленно, вам на помощь может прийти профайлер Dev-C++. Это инструмент, который выясняет, сколько времени затрачивает ваша программа на выполнение тех или иных действий, и позволяет вам сосредоточить свои усилия на наиболее "узком" месте программы.

Для включения профайлера воспользуйтесь командой меню Сервис => Параметры компилятора ( Tools => Compiler Options ), затем выберите вкладку Настройки ( Settings ), в левой части окна — Профилирование кода ( Code profiling ), а в правой установите опцию Генерировать профилирующую информацию для анализа ( Generate Profiling Info for Analysis ) равной Yes.

Давайте профилируем немного изменённую программу DeepCopy из главы 18, "Копирующий конструктор".

    //

    /* DeepCopy — программа для демонстрации профилирования */

    //

    #include <cstdio>

    #include <cstdlib>

    #include <iostream>

    #include <strings.h>

    using namespace std ;

    class Person

    {

      public :

        Person( char *pN )

        {

            pName = new char[ strlen( pN ) + 1 ] ;

            if ( pName != 0 )

            {

                strcpy( pName , pN ) ;

            }

        }

        Person( Person& p )

        {

            pName = new char[ strlen( p.pName ) + 1 ] ;

            if ( pName != 0 )

            {

                strcpy( pName , p.pName ) ;

            }

        }

        ~Person( )

        {

            delete pName ;

            pName = 0 ;

        }

      protected :

        char *pName ;

    } ;

_________________

340 стр. Часть 6. Великолепная десятка

        void fn1( Person &p )

    {

        /* Создаём новый объект */

        Person p1( p ) ;

    }

    void fn2( Person p )

    {

        /* Создаём новый объект */

        Person* p1 = new Person( p ) ;

        delete p1 ;

    }

    int main( int nNumberofArgs , char* pszArgs[ ] )

    {

        Person p( "Very, very long name" ) ;

        for ( int i = 0 ; i < 10000000 ; i++ )

        {

            fn1( p ) ;

            fn2( p ) ;

        }

        return 0 ;

    }

Эта программа вызывает функции fn1( ) и fn2( ) десять миллионов раз — просто нереально получить сколь-нибудь точную картину происходящего, если программа выполняется меньше секунды.

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

После выполнения программы воспользуйтесь командой меню Выполнить => Анализ профиля ( Execute => Profile Analysis ). Появляющееся при этом окно показано на рис. 30.1.

Рис. 30.1. Анализ профиля программы

_________________

341 стр. Глава 30. Десять основных возможностей Dev-C++

Интерпретация профиля требует определённой практики. В окне показаны функции, вызываемые в процессе выполнения программы ( в программе могут быть и другие функции, которые никогда не вызываются ). В первом столбце перечислены имена функций, за которыми следуют время их работы в процентах от общего времени работы программы. В нашем случае больше всего времени занимает выполнение конструктора копирования. В столбце Self Sees указано общее время, затраченное на выполнение этой функции.

Означает ли приведённая информация, что конструктор копирования — самая медленная функция программы? Не обязательно. Просто программа вызывает эту функцию чаще других — и в функции fn1( ), и в fn2( ).

Опустившись ниже по списку, мы видим, что fn2( ) работает почти в два раза больше, чем fn1( ). В основном это связано с тем, что функция main( ) передаёт функции fn2( ) объект Person по значению, что приводит к дополнительному вызову конструктора копирования.

_________________

342 стр. Часть 6. Великолепная десятка