使用Profiler分析程序性能
2016-07-29 00:00
417 查看
三个星期之前我向大家求助说,VS的Profiler分析程序性能时无法跟踪框架内部的方法调用。当时我做了不少尝试,例如下载并配置了.NET Framework的symbol文件和源代码,还尝试使用了ANTS Profiler和CLR Profiler等其他工具,最终还是没有成功。Ivony...老大在评论中告诉我说Sampling方式可以获得比Instrumentation更多的信息,不过我觉得Sampling得到的结果并不像我的目标那样干净,因此还是在寻找Instrumentation的方式。不过最终耗费了一个GTSC的支持点数,才被告知——的确应该使用Sampling。
那么我现在就来详细描述一下Profiler的使用方式吧。
首先,我们准备一个Console项目ProfilerSample,其中放入一段测试代码:
然后在菜单里选择Analyze - Profiler - New Performance Session,并将ProfilerSample加入Targets中:
请注意这里的Profile方式是Sampling。于是我们Profile这个程序(ProfilerSample),将会得到一个报表,于是我们可以浏览它的Call Tree:
这里显示的,已经是Expand All后的结果,可以看到调用非常之多。至于Column,除了Function Name之外,我只保留了“Inclusive Samples”和“Inclusive Samples %”两列,它们表示有多少次采样是落在这个方法的“调用树”上的。当然,您还可以选择Exlusive Samples等列,它与Inclusive的区别在于,Exlusive Samples不包括落在当前方法“子过程”里的采样。
此外,如果您看到的结果并不像截图里那么多,可能是由于Noise Reduction Options的设置关系。您可以点击上图工具栏中最右侧的按钮进行设置。
但是,看着这么一大堆信息我们会无从下手。因此,我们将滚动条拖到中段,可以发现ProfilerSample.Program.Main方法。对它点击右键,选择Set Root便会将其设为树装图的根。再折叠一些意义不大的方法(如mscorwks.dll),我们可以得到这样的结果:
经过观察,可以知道哪个方法,包括框架里的方法消耗的时间比较长。至于Sampling的细节,例如采样的频率,您可以在Performance Session的属性中进行设置。例如,可以选择不同的时钟周期长短进行采样。一般来说,采样频率越高,结果越准确,但这也意味着采样本身可能就会占用较多的时间——还好我们观察的主要是“比例”而不是绝对数量。
不过话说回来,我认为这个做法的目的还是在于观察框架“内部实现”的性能,有点探究“黑盒”的意味。在实际使用过程中,我们可能还是使用Instrumentations为好,因为这样得到的结果比较“干净”:
虽然信息较Sampling为少,但是对于我们进行性能优化来说已经足够了。因为此时结果里显示的都是我们自己写的方法,这也是我们唯一可以修改的东西。
那么我现在就来详细描述一下Profiler的使用方式吧。
首先,我们准备一个Console项目ProfilerSample,其中放入一段测试代码:
点此显示
点此隐藏 static void Main(string[] args) { var array = Enumerable.Range(1, 5).Select(i => new String((char)(i + 97), 5)).ToArray(); TestConvert(array); TestParse(array); TestTryParse(array); } private static List<Int32> TestParse(String[] strings) { Int32 intValue; List<Int32> intList = new List<int>(); for (int i = 0; i < 100000; i++) { intList.Clear(); foreach (String str in strings) { try { intValue = Int32.Parse(str); intList.Add(intValue); } catch (System.ArgumentException) { } catch (System.FormatException) { } catch (System.OverflowException) { } } } return intList; } private static List<Int32> TestTryParse(String[] strings) { Int32 intValue; List<Int32> intList = new List<int>(); Boolean ret; for (int i = 0; i < 100000; i++) { intList.Clear(); foreach (String str in strings) { ret = Int32.TryParse(str, out intValue); if (ret) { intList.Add(intValue); } } } return intList; } private static List<Int32> TestConvert(String[] strings) { Int32 intValue; List<Int32> intList = new List<int>(); for (int i = 0; i < 100000; i++) { intList.Clear(); foreach (String str in strings) { try { intValue = Convert.ToInt32(str); intList.Add(intValue); } catch (System.FormatException) { } catch (System.OverflowException) { } } } return intList; }
然后在菜单里选择Analyze - Profiler - New Performance Session,并将ProfilerSample加入Targets中:
请注意这里的Profile方式是Sampling。于是我们Profile这个程序(ProfilerSample),将会得到一个报表,于是我们可以浏览它的Call Tree:
这里显示的,已经是Expand All后的结果,可以看到调用非常之多。至于Column,除了Function Name之外,我只保留了“Inclusive Samples”和“Inclusive Samples %”两列,它们表示有多少次采样是落在这个方法的“调用树”上的。当然,您还可以选择Exlusive Samples等列,它与Inclusive的区别在于,Exlusive Samples不包括落在当前方法“子过程”里的采样。
此外,如果您看到的结果并不像截图里那么多,可能是由于Noise Reduction Options的设置关系。您可以点击上图工具栏中最右侧的按钮进行设置。
但是,看着这么一大堆信息我们会无从下手。因此,我们将滚动条拖到中段,可以发现ProfilerSample.Program.Main方法。对它点击右键,选择Set Root便会将其设为树装图的根。再折叠一些意义不大的方法(如mscorwks.dll),我们可以得到这样的结果:
经过观察,可以知道哪个方法,包括框架里的方法消耗的时间比较长。至于Sampling的细节,例如采样的频率,您可以在Performance Session的属性中进行设置。例如,可以选择不同的时钟周期长短进行采样。一般来说,采样频率越高,结果越准确,但这也意味着采样本身可能就会占用较多的时间——还好我们观察的主要是“比例”而不是绝对数量。
不过话说回来,我认为这个做法的目的还是在于观察框架“内部实现”的性能,有点探究“黑盒”的意味。在实际使用过程中,我们可能还是使用Instrumentations为好,因为这样得到的结果比较“干净”:
虽然信息较Sampling为少,但是对于我们进行性能优化来说已经足够了。因为此时结果里显示的都是我们自己写的方法,这也是我们唯一可以修改的东西。
相关文章推荐
- 想计划做一套Atlas的控件集合
- 趣味编程:将事件视为对象
- 偷得浮生半日闲
- 中央政治局常委的职业生涯对大家的启迪(转载)
- 受经济危机影响,老赵开始变卖家产了
- 数组排序方法的性能比较(1):注意事项及试验
- 可能是最漂亮的非静态Page Method解决方案
- 支持DomainRoute的URL构造辅助方法
- 使用Fiddler辅助观看InfoQ的视频
- 真有必要去除HTML中的空白字符吗?
- 随便说说:在ASP.NET应用程序中上传文件
- 趣味编程:从字符串中提取信息(参考答案 - 下)
- 紧急求助:Captivate发布后没有声音
- 一个我在研究Atlas Control Toolkit时做的尝试:ImageGalleryExtender
- IE7 - 千呼万唤始出来
- 从.NET中委托写法的演变谈开去(下):性能相关
- 微软十大软件开发英雄评选
- Why Java Sucks and C# Rocks(1):比较的意义与目的
- 适合C# Actor的消息执行方式(2):C# Actor的尴尬
- FAQ - 什么是软件工厂?(翻译)