Spec-Zone.ru › Octave 9

13.7 Пример работы профилировщика

Ниже приведён краткий пример сеанса профилирования. Подробное описание функций профилировщика см. в разделе Профилирование. Рассмотрим следующий код:

global N A;

N = 300;
A = rand (N, N);

function xt = timesteps (steps, x0, expM)
  global N;

  if (steps == 0)
    xt = NA (N, 0);
  else
    xt = NA (N, steps);
    x1 = expM * x0;
    xt(:, 1) = x1;
    xt(:, 2 : end) = timesteps (steps - 1, x1, expM);
  endif
endfunction

function foo ()
  global N A;

  initial = @(x) sin (x);
  x0 = (initial (linspace (0, 2 * pi, N)))';

  expA = expm (A);
  xt = timesteps (100, x0, expA);
endfunction

function fib = bar (N)
  if (N <= 2)
    fib = 1;
  else
    fib = bar (N - 1) + bar (N - 2);
  endif
endfunction

Если выполнить две основные функции, получим:

tic; foo; toc;
⇒ Elapsed time is 2.37338 seconds.

tic; bar (20); toc;
⇒ Elapsed time is 2.04952 seconds.

Однако это не даёт много информации о том, на что тратится время; например, о том, является ли более затратным единственный вызов expm или само рекурсивное выполнение временных шагов. Чтобы получить более подробную картину, можно воспользоваться профилировщиком.

profile on;
foo;
profile off;

data = profile ("info");
profshow (data, 10);

Будет выведена таблица вида:

#  Function Attr     Time (s)        Calls
---------------------------------------------
   7      expm             1.034            1
   3  binary *             0.823          117
  41  binary \             0.188            1
  38  binary ^             0.126            2
  43 timesteps    R        0.111          101
  44        NA             0.029          101
  39  binary +             0.024            8
  34      norm             0.011            1
  40  binary -             0.004          101
  33   balance             0.003            1

В таблице перечислены отдельные выполненные функции (только 10 наиболее значимых) и приведена информация о каждой из них. Записи, такие как «binary *», обозначают операторы, остальные записи — обычные функции. Сюда входят как встроенные функции, например expm, так и наши собственные подпрограммы (например, timesteps). Из этого профиля сразу видно, что expm занимает наибольшую долю времени выполнения, хотя вызывается всего один раз. Вторая по затратности операция — умножение матрицы на вектор в подпрограмме timesteps. 6

Однако время — не единственная информация, доступная в профиле. Столбец атрибутов показывает, что timesteps вызывает себя рекурсивно. В данном примере это, возможно, не так примечательно (поскольку и без того очевидно), но в более сложной ситуации такая информация может оказаться полезной. Что касается вопроса о том, почему в выводе появился «binary \», это тоже легко объяснить. Обратите внимание, что data — это массив структур (Массивы структур), содержащий поле FunctionTable. В нём хранятся исходные данные для показанного профиля. Число в первом столбце таблицы задаёт индекс, по которому можно найти соответствующую функцию. Если посмотреть data.FunctionTable(41), получим:

scalar structure containing the fields:

    FunctionName = binary \
    TotalTime =  0.18765
    NumCalls =  1
    IsRecursive = 0
    Parents =  7
    Children = [](1x0)

Здесь снова приведена информация из таблицы, но добавлены поля Parents и Children. Это массивы, содержащие индексы функций, которые напрямую вызвали рассматриваемую функцию (в данном случае это запись 7, expm) или были вызваны ею (таких функций нет). Следовательно, оператор обратной косой черты использовался внутри expm.

Теперь рассмотрим bar. Для этого начнём новый сеанс профилирования (это делает profile on; перед повторным запуском профилировщика старые данные удаляются):

profile on;
bar (20);
profile off;

profshow (profile ("info"));

Результат:

#            Function Attr     Time (s)        Calls
-------------------------------------------------------
   1                 bar    R        2.091        13529
   2           binary <=             0.062        13529
   3            binary -             0.042        13528
   4            binary +             0.023         6764
   5             profile             0.000            1
   8               false             0.000            1
   6              nargin             0.000            1
   7           binary !=             0.000            1
   9 __profiler_enable__             0.000            1

Неудивительно, что bar также является рекурсивной. При рекурсивном вычислении числа Фибоначчи неоптимальным способом она была вызвана 13 529 раз, и большая часть времени ушла на выполнение самой bar.

Наконец, предположим, что мы хотим профилировать выполнение foo и bar вместе. Поскольку данные о времени выполнения bar уже собраны, можно перезапустить профилировщик, не очищая имеющиеся данные, и собрать недостающую статистику о foo. Для этого выполните:

profile resume;
foo;
profile off;

profshow (profile ("info"), 10);

Как видно из таблицы ниже, теперь оба профиля объединены.

#  Function Attr     Time (s)        Calls
---------------------------------------------
   1       bar    R        2.091        13529
  16      expm             1.122            1
  12  binary *             0.798          117
  46  binary \             0.185            1
  45  binary ^             0.124            2
  48 timesteps    R        0.115          101
   2 binary <=             0.062        13529
   3  binary -             0.045        13629
   4  binary +             0.041         6772
  49        NA             0.036          101

© 1996–2026 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v9.4.0/Profiler-Example.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API