Как я могу профилировать подпрограмму без использования модулей? - PullRequest
3 голосов
/ 25 апреля 2010

У меня возникает соблазн переименовать этот вопрос: «Посмотри на этот кирпичик. К какому типу домов он относится? '

Вот ситуация: меня фактически попросили профилировать некоторые подпрограммы, не имеющие доступа ни к профилировщикам (даже Devel::DProf), ни к Time::HiRes. Цель этого упражнения - «найти» узкие места.

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

Код работает под Unix. Самая близкая вещь, которую я вижу к моей потребности - это perlfaq8 , но это, кажется, не помогает (я не знаю, как сделать syscall, и мне интересно, повлияет ли это на синхронизацию кода непредсказуемо).

Не ваш типичный ежедневный ТАК вопрос ...

Ответы [ 4 ]

7 голосов
/ 25 апреля 2010

Этот метод должен работать.

По сути, идея в том, что если вы запустите Perl с флагом -d, он перейдет в отладчик. Затем, когда вы запускаете программу, ctrl-Break или ctrl-C должны заставить ее остановиться в середине того, что она делает. Затем вы можете набрать T, чтобы показать стек, и проверить любые другие переменные, если хотите, прежде чем продолжить.

Сделайте это примерно 10 или 20 раз. Любая строка кода (или любая функция, если вы предпочитаете), которая стоит значительный процент времени, будет отображаться примерно в этом проценте выборок стека, поэтому вы не пропустите ее.

Например, если строка кода (обычно вызов функции) стоит 20% времени, и вы останавливаете программу 20 раз, вы увидите эту строку на 4 выборках стека, дайте или возьмите 1,8 выборки. Количество времени, которое можно сэкономить, если вы можете избежать выполнения этой строки или выполнить ее намного меньше, сокращают общее время выполнения на 20%.

Тогда вы можете повторить это, чтобы найти больше проблем.

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

1 голос
/ 25 апреля 2010
  1. Что касается syscall, в этом посте есть довольно хороший пример: http://www.cpan.org/scripts/date_and_time/gettimeofday

    Я думаю, что это достаточно ясно даже для тех, кто никогда раньше не пользовался syscall (как я:)

  2. Могу ли я спросить, в чем специфика "отсутствия доступа"?

    Обычно можно получить доступ к модулям CPAN, даже в тех случаях, когда их установка в центральном месте отсутствует на платах. Есть проблема с загрузкой модуля? Устанавливаете его в своем домашнем каталоге? Использование программного обеспечения с включенным модулем?

    Если один из них является зависанием, его, вероятно, можно исправить ... если это какая-то политика компании, это бесценно: (

0 голосов
/ 04 мая 2010

Для каждой подпрограммы создайте обертку вокруг нее, которая сообщает время в каком-либо формате, который вы можете экспортировать в нечто вроде R, базу данных, Excel или что-то подобное (CSV был бы хорошим выбором). Добавьте что-то подобное в свой код. Если вы используете Perl менее 5.7 (когда Time :: HiRes был впервые добавлен в ядро), используйте syscall, как упомянуто выше, вместо функций Time :: HiRes ниже.

INIT {
    sub wrap_sub {
        no strict 'refs';
        my $sub = shift;
        my $subref = *{$sub}{CODE};
        return sub {
            local *__ANON__ = "wrapped_$sub";
            my $fsecs = Time::HiRes::gettimeofday();
            print STDERR "$sub,$fsecs,";
            if (wantarray) {
               @return = eval { $subref->(@_) } or die $@;
            } else {
               $return[0] = eval { $subref->(@_) } or die $@;
            }

            $fsecs = Time::HiRes::gettimeofday();
            print STDERR "$fsecs\n";
            return wantarray ? @return : $return[0];
        };
    }
    require Time::HiRes;
    my @subs = qw{the subs you want to profile};
    no strict 'refs';
    no warnings 'redefine';
    foreach my $sub (@subs) {
        *{$sub} = wrap_sub($sub);
    }    
}

Замените 'подпрограммы, которые вы хотите профилировать', подпрограммами, которые вам нужны, и используйте дескриптор файла open () вместо STDERR, если вам нужно, помня, что вы можете получить результаты прогона отдельно от вывода сценария (в Unix, с оболочками bourne, korn и bash), как это

perl ./myscript.pl 2>myscript.profile
0 голосов
/ 04 мая 2010

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

То, что вы хотите , и что ваш босс хочет, хотя он или она может не знать об этом, - это использовать Devel :: NYTProf , чтобы действительно хорошо профилировать ваш код и выполнение работы вместо того, чтобы ждать, пока вы частично продублируете его функции, изучая, как это делается.

Комментарий, который вы сделали о «личном использовании», не имеет смысла. Вы выполняете работу для работы, и работа должна быть выполнена, и вам нужны (или ваш менеджер должен заставить вас) ресурсы для выполнения этой работы. «Личное использование» не похоже на это.

Это вопрос о том, что кто-то еще отказывается подписать модуль, чтобы он был установлен на компьютере, на котором выполняется измеряемое программное обеспечение? Это вопрос лицензирования? Разве не разрешается устанавливать произвольное программное обеспечение на производственном компьютере (понятно, но должен быть какой-то способ протестировать программное обеспечение до его запуска - я надеюсь - профилировать его там)?

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

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