4

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

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

这个结论正确吗?线分析器是否需要解析树,而这是否只需要(除了时间记录)?


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

更新 2:这是一个众所周知的Python 行分析器的链接,以防它有助于回答这个问题。我还不能确定它相对于解析的行为。恐怕 Matlab 分析器的代码无法访问。

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

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

更新 4:关于使用线路分析器与调用堆栈分析器 -这篇关于使用调用堆栈分析器(Rprof()在这种情况下)的帖子举例说明了为什么使用调用堆栈而不是通过线路分析器直接分析事情会很痛苦.

4

2 回答 2

3

听起来您所说的线分析器是指测量每条线内花费的时间(即检测)的东西。我希望你所说的时间是挂钟时间,因为在真正的大型软件中,如果你只看 CPU 时间,你会错过很多。

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

一行代码所花费的时间百分比就是包含它的堆栈样本的百分比。由于您在线路级别工作,因此无需区分独占(自身)时间和包含时间。这是因为线路的活动时间百分比很重要,无论是调用另一个函数、调用盲系统函数还是调用微码。

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

此外,您不必担心递归。如果一行代码在递归函数中并且在样本中出现多次,那没关系。它仍然算作只有一个包含该行的样本。没关系的原因是,如果可以以某种方式使该代码行不花时间(例如通过删除它),那么该示例就不会发生。因此,包含该行的样本将从样本集中删除,并且程序的总时间将减少与删除的样本分数相同的数量。这与递归无关。

您也不需要计算一行代码执行了多少次,因为对于定位您应该优化的代码而言,重要的数字是它处于活动状态的时间百分比。

以下是对这些问题的更多解释

于 2011-09-05T20:56:29.627 回答
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映射到同一行...

祝你好运!

于 2011-09-28T19:23:24.930 回答