本节书摘来自异步社区《编程珠玑(续)(修订版)》一书中的第1章,第1.4节开发性能监视工具,作者【美】Jon Bentley,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.4 开发性能监视工具
开发一个真正的性能监视工具是件困难的事情。Peter Weinberger⑤开发了C行计数性能监视工具,我们前面看到的输出就是这个工具产生的。他在几个月时间内断断续续干了好几周才完成这个项目。本节描述如何更容易地开发一个简化版本。
Dick Sites声称他的朋友“在某个周末实现了语句计数”。我觉得这简直难以置信,于是我决定要试着为附录A描述的Awk语言(这种语言还没有性能监视工具)开发一个性能监视工具。几小时后,当我运行程序P6的Awk版本时,我的性能监视工具生成了如下输出。
程序P6及性能监视工具生成的输出
BEGIN { <<<1>>>
n = 1000
x[0] = 2; xc = 1
print 2
for (i = 3; i <= n; i++) { <<<998>>>
if (prime(i)) { <<<167>>>
print i
}
}
exit
}
function prime(n, i) { <<<998>>>
for (i=0; x[i]*x[i]<=n; i++) { <<<2801>>>
if (n % x[i] == 0) { <<<831>>>
return 0
}
}
{ <<<167>>> }
x[xc++] = n
return 1
}
在左花括号后尖括号内的数显示该语句块被执行了多少次。幸运的是,这些计数与C行计数器产生的计数一样。
我的性能监视工具包含两个5行的Awk程序。第一个程序读Awk源程序并且写一个新程序,其中在每个语句块开始的地方给不同的计数器加1;而在执行结束时,一个新的END动作(见附录A)把所有计数写入一个文件。当这样得出的程序运行时,就生成一个计数文件。第二个程序读出这些计数,把这些计数合并到源文本中。带性能监视的程序大约比原来的程序慢25%,而且并不是所有的Awk程序都能正确处理——为了监视几个程序的性能,我不得不做出整行(one-line)的修改。但对于所有这些缺点来说,搭起一个能运行的性能监视工具,花几小时并不算什么大投入。在AWK Programming Language一书的7.2节给出了一个类似的Awk性能监视工具的细节,本书2.6节引用了这本书。
人们实现过一些快速性能监视工具,但鲜见报道。下面举几个例子。
在1983年8月的BYTE杂志上,Leas和Wintz描述了一个性能监视工具,用一个20行的6 800汇编语言程序来实现。
贝尔实验室的Howard Trickey在一小时内用Lisp实现了函数计数,办法是修改defun,在进入每个函数时给计数器加1。
1978年,Rob Pike⑥用20行Fortran程序实现了一个时间性能监视工具。在CALL PROFIL(10)之后,后续的CPU时间被计入计数器10。
在这些系统和许多其他系统上,在一晚上写出一个性能监视工具是可能的。在你第一次使用所得到的性能监视工具时,这个工具轻易就能节省超过一个晚上的工作量。