解决性能问题必须使用Profiler,无论是自己写的实验代码还是一些高级工具,没有数据,而是凭感觉来解决性能问题在绝大部分情况是不靠谱的。VSTS包含了Profiler,也经常见一些博客上用Profiler得到的数据进行性能分析,其中最著名的莫过于Rico Mariani的Performance Quiz系列了。使用VSTS的Profiler可以收集程序运行过程中每个方法的调用次数,所消耗的总时间等等,一目了然,但是我在使用过程中却出现了问题。
例如就拿这篇文章来说,它详细分析了各种解析字符串的方式,最终用Profiler生成的Call Tree如下:
![GoodStringsDetail.jpg](http://home.cwru.edu/~ixh10/Blog/Parse/GoodStringsDetail.jpg)
然而,在我却只能收集到:
![o_my-profile-result.png](https://i-blog.csdnimg.cn/blog_migrate/bf1248e6b18351fcd8efa76a6e009e8f.png)
看出区别来了不?我只能收集到我写的方法,或是我调用的.NET框架的方法,而我无法获得框架内部方法的调用情况。我搜索了各种资料,尝试了各种可以的选项,都没有效果。后来我又尝试了ANTS Profiler,效果也是一样(只能获得“公开情报”)。于是我怀疑是不是缺少pdb文件的缘故,于是根据Shawn Burke的文章设置了Symbol Server——没有效果。我不甘心,又使用NetMassDownloader下载了pdb文件和.NET Framework源代码,并在VS里进行了设置:
![o_vs08-symbol-path.png](https://i-blog.csdnimg.cn/blog_migrate/7342d33e95a6b1e7cfacdde0f9fb3eae.png)
结果,框架内部方法的调试都正常,但是Profiler的结果还是没有任何改变。而且,等我作完这些尝试之后我忽然意识到,这很可能不是symbol的问题。为什么这么说呢?因为我可以使用CLR Profiler其实可以得到这些结果:
![o_clr-profiler-call-tree.png](https://i-blog.csdnimg.cn/blog_migrate/81816d7d4a9fdc3c0f2428e694118f6e.png)
CLR Profiler给出了各方法调用情况,但是我……还没有完全看懂其中的数据,它似乎没有像VS中那么友好的Call Tree展示方式。幸运的是,如果数据是充分的话,我们也可以自己进行分析。而且CLR Profiler是公开源代码的,这样即使有不足指出,我们也可以进行改进。但是,Visual Studio的Profiler又是怎么回事呢?