c#分析器是如何工作的

本文关键字:工作 何工作 分析器 | 更新日期: 2023-09-27 17:53:13

我很好奇一个典型的c#分析器是如何工作的?

虚拟机中有特殊的钩子吗?

是否容易扫描字节码的函数调用和注入调用启动/停止定时器?

或者这真的很难,这就是为什么人们花钱买工具来做这件事?

(作为旁注,我发现有点有趣,因为它是如此罕见-谷歌完全错过了船在搜索"c#剖析器是如何工作的?"根本不工作-结果是关于空调…)

c#分析器是如何工作的

有一个免费的CLR剖析器由微软,版本4.0。

https://www.microsoft.com/downloads/en/details.aspx?familyid=be2d842b fdce - 4600 - 8 d32 a3cf74fda5e1

顺便说一句,在CLR Profiler文档中有一个很好的部分详细描述了它是如何工作的,第103页。源代码是发行版的一部分。

是否容易扫描字节码函数调用和注入调用启动/停止计时器吗?

或者真的很难,这就是原因人们花钱买工具来做这些?

注入调用非常困难,需要工具来完成。

这不仅很难,而且是一种非常间接的找到瓶颈的方法。原因是瓶颈是代码中的一个或几个语句,它们占用了很大比例的时间,这些时间本可以大大减少——也就是说,它不是真正必要的,也就是说,它是浪费的。如果你能知道你的一个例程的平均时间(包括IO时间),如果你能把它乘以它被调用的次数,再除以总时间,你就能知道这个例程所花费的时间的百分比。如果这个百分比很小(比如10%),你可能在其他地方有更大的问题。如果这个百分比更大(比如20%到99%),你可能会在例程中遇到瓶颈。因此,现在您必须在例程中查找它,查看它调用的东西以及它们所花费的时间。此外,您还希望避免被递归(调用图的麻烦)所迷惑。

有分析器(如Zoom for Linux, Shark, &其他的)以不同的原则工作。原理是有一个函数调用堆栈,在所有的时间内,一个例程负责(要么完成工作,要么等待其他例程完成它请求的工作),它在堆栈上。所以如果它占了50%的时间,那么这就是它在堆栈上的时间,不管它被调用了多少次,或者每次调用花费了多少时间。不仅例程在堆栈上,而且花费时间的特定代码行也在堆栈上。你不需要去找他们。另一件你不需要的东西是测量的精度。如果您取了10,000个堆栈样本,那么错误线的测量值为50 +/- 0.5%。如果你取100个样本,它们将被测量为50 +/- 5%如果取10个样本,它们的值是50 +/- 16%在任何情况下,你都能找到它们,这就是你的目标。(递归不重要。它的意思是,给定的行可以在给定的堆栈样本中出现多次。

在这个问题上,有很多困惑。无论如何,对于发现瓶颈最有效的分析器是那些在挂钟时间内对堆栈进行采样并按行报告百分比的分析器。(这很容易看出关于分析的某些误解是否被正确看待了。)

1)没有所谓的"典型"。人们通过各种方式收集概要信息:对PC进行时间采样,检查堆栈跟踪,捕获方法/语句/编译指令的执行计数,在代码中插入探针以收集计数,并可选择调用上下文以在调用上下文的基础上获取概要数据。每一种技术都可以用不同的方式实现。

2)有分析"c#"和分析"CLR"。在MS世界中,您可以分析CLR并将CLR指令位置反翻译为c#代码。我不知道单声道是否使用相同的CLR指令集;如果没有,那么您就不能使用MS CLR分析器;你必须使用单声道IL分析器。或者,你可以编写c#源代码来收集分析数据,然后在MS、Mono或某些c#兼容的自定义编译器上编译/运行/收集这些数据,或者在WinCE等嵌入式系统中运行c#,这些系统空间很宝贵,clr内置功能往往会被遗漏。

检测源代码的一种方法是使用源到源转换,将代码从其初始状态映射到包含数据收集代码以及原始程序的代码。这篇关于插装代码来收集测试覆盖率数据的论文展示了一个程序转换系统如何通过插入语句来插入测试覆盖率探测,这些语句在执行代码块时设置特定于块的布尔标志。计数分析器为这些探测替换反递增指令。时序分析器为这些探针插入时钟快照/增量计算。我们的c#分析器实现了c#源代码的计数和定时分析;它还通过使用更复杂的探测收集执行路径来收集调用图数据。因此,它可以通过这种方式在调用图上生成计时数据。这个方案适用于任何地方,你可以得到一个半体面的分辨率时间值。

这是一篇讨论仪器和抽样方法的长篇文章的链接:

http://smartbear.com/support/articles/aqtime/profiling/