Требуется ли для профилировщика строки для кода дерево разбора и достаточно ли этого? - PullRequest
4 голосов
/ 05 сентября 2011

Я пытаюсь определить, что необходимо для написания профилировщика строк для языка, например, доступных для Python и Matlab.

Наивный способ интерпретации «профилировщика строк» ​​состоит в предположении, что можно вставитьвремя регистрации вокруг каждой строки, но определение строки зависит от того, как парсер обрабатывает пробелы, что является только первой проблемой.Кажется, что нужно использовать дерево разбора и вставить временные интервалы вокруг отдельных узлов.

Правильно ли сделан этот вывод?Требуется ли для профилировщика линии дерево разбора и требуется ли все это (помимо регистрации времени)?


Обновление 1: предложение вознаграждения за это, поскольку вопрос все еще не решен.

Обновление 2: Вот ссылка на хорошо известный профилировщик строки Python на случай, если он поможет ответить на этот вопрос.Я еще не был в состоянии сделать головы или хвосты его поведения относительно разбора.Боюсь, что код для профилировщика Matlab недоступен.

Также обратите внимание, что можно сказать, что ручное оформление входного кода устранит необходимость в дереве разбора, но это не автоматический профилировщик.

Обновление 3: хотя этот вопрос не зависит от языка, он возник из-за того, что я думаю о создании такого инструмента для R (если он не существует, и я его не нашел).

Обновление 4: Относительно использования профилировщика линии по сравнению с профилировщиком стека вызовов - этот пост , касающийся использования профилировщика стека вызовов (* в данном случае Rprof()), иллюстрирует, почему это может быть болезненноработать со стеком вызовов, а не напрямую анализировать данные через линейный профилировщик.

Ответы [ 2 ]

3 голосов
/ 28 сентября 2011

Я бы сказал, что да, вам требуется дерево разбора (и источник) - как еще вы знаете, что составляет "строку" и допустимое утверждение?

Практическое упрощение, хотя может быть«оператор профилирования» вместо «профилировщик строк».В R дерево синтаксического анализа легко доступно: body(theFunction), поэтому должно быть достаточно легко вставить измерительный код вокруг каждого оператора.Еще немного поработав, вы можете вставить его вокруг группы операторов, принадлежащих одной строке.

В R тело функции, загружаемой из файла, обычно также имеет атрибут srcref, в котором указан источникдля каждой «строки» (фактически каждого оператора):

Вот пример функции (вставлен в «example.R»):

f <- function(x, y=3)
{
    a <- 0; a <- 1  # Two statements on one line
    a <- (x + 1) *  # One statement on two lines
        (y + 2)

    a <- "foo       
        bar"        # One string on two lines
}

Затем в R:

source("example.R")
dput(attr(body(theFunction), "srcref"))

Который печатает эту информацию строки / столбца:

list(structure(c(2L, 1L, 2L, 1L, 1L, 1L, 2L, 2L), srcfile = <environment>, class = "srcref"), 
    structure(c(3L, 2L, 3L, 7L, 9L, 14L, 3L, 3L), srcfile = <environment>, class = "srcref"), 
    structure(c(3L, 10L, 3L, 15L, 17L, 22L, 3L, 3L), srcfile = <environment>, class = "srcref"), 
    structure(c(4L, 2L, 5L, 15L, 9L, 15L, 4L, 5L), srcfile = <environment>, class = "srcref"), 
    structure(c(7L, 2L, 8L, 6L, 9L, 20L, 7L, 8L), srcfile = <environment>, class = "srcref"))

Как вы можете «видеть» (последние два числа в каждой структуре - начало / конец строки), выражения a <- 0 и a <- 1сопоставить с той же линией ...

Удачи!

3 голосов
/ 06 сентября 2011

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

Еще один способ сделать это - стек-сэмплирование по времени настенных часов, как в профилях Zoom и LTProf .Поскольку каждая строка образца стека может быть локализована в строке кода с использованием только файла карты или pdb, так же, как это делают отладчики, нет необходимости анализировать или изменять источник.

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

Преимущество просмотрапроценты, а не абсолютное время - вам не нужно беспокоиться о замедлении работы приложения, либо из-за самой выборки, либо из-за конкуренции с другими процессами, потому что эти вещи не сильно влияют на проценты.

Также вам не нужно беспокоиться о рекурсии.Если строка кода находится в рекурсивной функции и появляется более одного раза в образце, это нормально.Он по-прежнему считается только одним образцом, содержащим строку.Причина в том, что все в порядке, если эту строку кода можно каким-то образом заставить не тратить время (например, удалив ее), то этот образец не возник бы.Поэтому образцы, содержащие эту строку, будут удалены из набора образцов, и общее время программы уменьшится на ту же величину, что и доля удаленных образцов.Это независимо от рекурсии.

Вам также не нужно подсчитывать, сколько раз выполняется строка кода, потому что число, которое имеет значение для поиска кода, который вы должны оптимизировать, - это процент времени его активности.

Вот подробное объяснение этих вопросов.

...