代码的行分析器是否需要解析树并且足够吗?

时间:2011-09-05 15:12:15

标签: python r language-agnostic profiling parse-tree

我正在尝试确定为一种语言编写行分析器所需的内容,例如可用于Python和Matlab的那些。

解释“line profiler”的一种天真的方式是假设可以插入每行记录时间,但是行的定义取决于解析器如何处理空格,这只是第一个问题。似乎需要使用解析树并在各个节点周围插入时序。

这个结论是否正确?行分析器是否需要解析树,是否需要所有这些(超出时间记录)?


更新1:为此提供赏金,因为问题仍未得到解决。

更新2:以下是知名Python line profiler的链接,以防有助于回答此问题。我还没有能够解析它相对于解析的行为。我担心Matlab探查器的代码无法访问。

另请注意,可以说手动修饰输入代码将消除对解析树的需求,但这不是自动分析器。

更新3:虽然这个问题与语言无关,但这是因为我正在考虑为R创建这样的工具(除非它存在且我还没有找到它)。

更新4:关于使用线路分析器与调用堆栈分析器的使用 - this post与使用调用堆栈分析器(在这种情况下为Rprof())相关,举例说明了为什么使用它可能会很痛苦。调用堆栈而不是通过行分析器直接分析事物。

2 个答案:

答案 0 :(得分:3)

这听起来像是行轮廓仪的意思是衡量每行内所花费的时间(即仪表)。 我希望你在时间上的意思是挂钟时间,因为在真正的大小合适的软件中,如果你只看CPU时间,你就会失去很多。

另一种方法是在挂钟时间进行堆叠采样,如ZoomLTProf剖析器。 由于堆栈样本的每一行都可以仅使用map或pdb文件本地化为一行代码,因此与调试器一样,不需要解析或修改源代码。

一行代码占用的时间百分比只是包含它的堆栈样本的百分比。 由于您在线级工作,因此无需区分独占(自我)时间和包含时间。 这是因为线路的活跃时间百分比是重要的,无论是对另一个功能的调用,对盲系统功能的调用,还是对微码的调用。

查看百分比而不是绝对时间的优点是,您无需担心应用程序因采样本身或与其他流程竞争而变慢,因为这些事情不会影响很高的百分比。

此外,您不必担心递归。 如果一行代码在递归函数中并且在样本上出现不止一次,那就没问题。 它仍然只计为包含该行的一个样本。 可以的理由是,如果该行代码可以某种程度上不花时间(例如通过删除它)那样就不会发生。 因此,包含该线的样品将从样品组中移除,并且程序的总时间将减少与去除的样品的分数相同的量。 这与递归无关。

您也不需要计算一行代码的执行次数,因为您应该优化的代码定位数量是它激活的时间百分比。

以下是这些问题的more explanation

答案 1 :(得分:3)

我会说是的,你需要一个解析树(以及源代码) - 你怎么知道什么是“行”和有效的陈述?

实际的简化虽然可能是“语句分析器”而不是“行分析器”。 在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 <- 0a <- 1映射到同一行......

祝你好运!