现代软件工程讲义 2 开发技术 - 效能分析

9.4  VSTS 效能分析工具

啊,效能分析,Performance!这是每一个程序员都梦想的事儿,让自己的程序跑得又快又好,最好是比别的同学快一个数量级,别人的程序是O(N^2),而我的程序是O(n*logN),或者是O(N),这是多爽的一项成就呀!VSTS提供了方便的效能分析工具,让我们能很快地找到程序的效能瓶颈,从而能有的放矢,改进程序。下面我们看一个具体的例子。

和同学们的作业类似,有这样一道题:

写一个程序,分析一个文本文件中各个词出现的频率,并且把频率最高的10个词打印出来。

果冻很快用C#写好了程序,命名为WordFreq.exe,然后运行了一下,验证了正确性,程序的基本框架如代码清单9-3所示(全部程序可以在移山社区网站下载):

代码清单9-3  WordFreq程序,程序框架

DoIt()
{
    ProcessFile()  //store all words in a big buffer
    ProcessBuffer()  //calculate and store the frequency of each word
    OutputResult()   //output top 10
}
 
ProcessBuffer()
{
    GetOneWord()   //get one word from buffer
    FreqOneWord()
}
 
FreqOneWord(word)
{
Find the word in the array list,
If (found)
    Update the frequency
If (not found)
    Add the word in the array list with frequency = 1
}
 
OutputResult()
{
ArrayList.Sort()   //sort the array
Output Top 10 entry;
}

文本文件大约是30KB~300KB大小。在运行效能分析之前,阿超让大家预计占用时间最多的是什么函数,或者哪些语句。大家众说纷纭,有的说是处理文件,因为I/O很花时间,有的说是排序,有的说是处理每个词。还有人建议应该把排序和处理每一个词同时进行,这样就能加快速度。

我们看看到底会是什么情况。第一步,要确保编译的程序是Release版本。然后在VS界面中选中Tools | Performance Tools | Performance Wizard(如图9-1所示)。

图9-1  效能分析,选择分析方法

我们看到可以选择两种分析方法:

(1)        抽样(Sampling)

(2)        代码注入(Instrumentation)

通俗地解释,抽样就是当程序运行时,Visual Studio时不时看一看这个程序运行在哪一个函数内,并记录下来,程序结束后,Visual Studio就会得出一个关于程序运行时间分布的大致的印象。这种方法的优点是不需要改动程序,运行较快,可以很快地找到瓶颈。但是不能得出精确的数据,代码中的调用关系(CallTree)也不能准确表示。

另一方面,代码注入就是将检测的代码加入到每一个函数中,这样程序的一举一动都被记录在案,程序的各个效能数据都可以被精准地测量。这一方法的缺点是程序的运行时间会大大加长,还会产生很大的数据文件,数据分析的时间也相应增加。同时,注入的代码也影响了程序真实的运行情况(这有点像量子物理学中的“测试的光线干扰了测试物体本身”的现象)。

我们一般的做法是,先用抽样的方法找到效能瓶颈所在,然后对特定的模块用代码注入的方法进行详细分析。

对程序进行效能分析,我们先要弄清下面这几个名词,如表9-1所示:

表9-1  效能分析的名词解释


名  词


含  义


调用者Caller


函数Foo()中调用了Bar(),Foo()就是调用者


被调用函数Callee


见上,Bar()就是被调用函数


调用关系树Call Tree


从程序的Main()函数开始,调用者和被调用函数就形成了一个树形关系——调用树


消逝时间Elapsed Time


从用户的角度来看程序运行所花的时间。当用户看到一个程序没有反应,用户并不知道程序此时是在运行自己的代码,还是被调度出去了,或者操作系统此时正在忙别的事情


应用程序时间Application Time


应用程序占用CPU的时间,不包括CPU在核心态时花费的时间

续表


名  词


含  义


本函数时间Exclusive Time


所有在本函数花费的时间,不包括被调用者使用的时间


所有时间Inclusive Time


包含本函数和所有调用者使用的时间

理解了上面的各种概念后,我们就不难理解“消逝的本函数时间(Elapsed Exclusive Time)”等其他组合名词所代表的概念了。

我们先进行抽样分析,在效能浏览器(Performance Explorer)中开始效能分析即可。

图9-2是WordFreq程序处理一个30KB的文本文件时的情况:

图9-2  用抽样的方法分析效能

大家可以看到最花时间的三个函数是:

WordFreq.Freq.FreqOneWord(string)

System.String.EqualsHelper(string,string)

System.Collections.ArrayList.get_Item(int32)

三个函数加起来占用了整个程序84%的时间。看来我们得分析为什么这三个函数会被调用得这么频繁,开销这么大了。

我们现在可以进行代码注入的分析,同样运行程序后,我们看看图9-3的调用树(Call Tree)报告。

图9-3  代码注入方法产生的效能报告

结合实际的代码(见代码清单9-4),可以看到在WordFreq. FreqOneWord函数中,究竟发生了什么:

代码清单9-4  FreqOneWord()

 private void FreqOneWord(string w)
        {
            // see if we have a match, if not, add it to the end,
            // then assign it initial frequency 1;
            // if yes, inc the frequency by 1
            for (int i = 0; i < m_wordList.Count; i++)
            {
                Frequency fi = (Frequency)m_wordList[i];
 
                if (fi.str == w)
                {
                    fi.n++;
                    return;
                }
            }
 
            //now we have to append it to the end.
            Frequency f = new Frequency();
            f.str = w;
            f.n = 1;
            m_wordList.Add(f);
        }
时间: 2024-10-13 05:53:14

现代软件工程讲义 2 开发技术 - 效能分析的相关文章

软件工程第三周作业-效能分析

运行三次ptime.exe,时间如下: 平均速度0.511s,我觉得挺快的. profile 等待更新.

软件工程第三次作业 - 效能分析

要求0:以 战争与和平 作为输入文件,重读向由文件系统读入.连续三次运行,给出每次消耗时间.CPU参数. 第一次运行结果: 本次程序运行所消耗的时间为1.2秒. 第二次运行结果: 本次程序运行所消耗的时间为936毫秒. 第三次运行结果: 本次程序运行所消耗的时间为975毫秒. 要求1:给出你猜测程序的瓶颈.你认为优化会有最佳效果,或者在上周在此处做过优化 (或考虑到优化,因此更差的代码没有写出) . 上周的代码我使用的是结构体数组来对分割好的单词进行存储并采用冒泡排序,效果非常不理想,统计完wa

2018年四川理工学院软件工程考试大纲(面向对象的软件开发技术概述)

2018年四川理工学院软件工程考试大纲(面向对象的软件开发技术概述)   1.面向对象软件开发,需要建立哪三种模型 ①.对象模型(用于描述系统的数据结构,定义了系统"对谁做") ②.动态模型(定义了系统"何时做") ③.功能模型(定义了系统"做什么") 2.面向对象软件开发 对象是指生活中的具体事物,面向对象软件开发是指根据生活中具体的事物为基本单位所进行的软件开发 3.面向对象软件开发的过程 面向对象分析(OOA).面向对象设计(OOD).面向

Android开发经典书籍下载——《Android 4高级编程》《疯狂Android讲义》《Android应用开发详解(郭宏志)》《Android应用案例开发大全》《Android 3D游戏开发技术》

这是我收集的关于android开发方面的经典书籍,高清PDF电子版,可以在我的百度网盘免费下载,希望对需要的朋友有帮助. 目录: <Android 4高级编程>(附完整源代码) <疯狂Android讲义> <Android应用开发详解(郭宏志)> <Android应用案例开发大全> <Android 3D游戏开发技术> <Android内核剖析 柯元旦> <深入理解Android  卷1> <深入理解Android

【Android应用开发技术:图像处理】Bitmap显示性能优化分析

作者:郭孝星 微博:郭孝星的新浪微博 邮箱:[email protected] 博客:http://blog.csdn.net/allenwells Github:https://github.com/AllenWells [Android应用开发技术:图像处理]章节列表 Bitmap经常会消耗大量内存而导致程序崩溃,常见的异常如下所示:java.lang.OutofMemoryError:bitmap size extends VM budget,因此为了保证程序的稳定性,我们应该小心处理程序

2017年软件工程第三次作业-2效能分析

要求0 以 战争与和平 作为输入文件,重读向由文件系统读入.连续三次运行,给出每次消耗时间.CPU参数       首先,我下载ptime.exe,不知道什么原因我下载下来以后运行老出现闪退现象.一直没法使用.我就接下来开始下载visual studio 2015,但是下载了一下午就是下不下来,我也很苦恼啊,电脑还是变成了巨难用,我下载的时候大概是缺少很多插件,我也不懂了.然后通过请教学长和同学,我使用了Very Sleepy CS软件来对功能进行效能分析. 由于我上次作业功能四没有实现,我没办

从传统软件工程到敏捷开发之我们到底需要什么样的方法

软件工程是上世纪七十年代提出来的概念,面对开发程序的规模越来越庞大,用户的需求越来越复杂等挑战,提出将软件开发工程化的概念,传统的软件开发方法有瀑布模型.螺旋模型.喷泉模型.RUP四类,它们注重文档的完整,程序的易读性,结构的完整性,属于重型软件开发方法.在过去的一段时间,传统软件工程的方法很好的适应了软件开发的需求,传统软件工程不仅关注软件构造方式的完美型,同时也注重总体的可预测性,以文档为驱动,按照需求分析.概要设计.详细设计.编码.测试.软件交付的流程来进行开发.在软件产业不是很发达.软件

我推崇的软件工程思想--敏捷开发

在前一篇博客中谈到了是上课学的是"上世纪"的软件工程思想,先买呢谈谈我推崇的软件工程思想----敏捷开发 为什么要敏捷开发 "没有人喜欢敏捷,但我们不得不敏捷.就像没有人喜欢工作,但你必须工作."这是我经常用来调侃敏捷的一句话. 试想一下,拿到一份完整详尽的需求文档,逐个功能Coding,测试部署上线.不需要再次确认需求,不会有人打断思路.没有需求更改,只要自己不犯错,不存在推倒重来这才是大部分开发人员最舒服的工作方式吧,简直太完美了.但它很像瀑布,一点都不敏捷.

手游服务器开发技术详解

从事游戏服务器开发差不多两年时间,两年间参与了不少项目,学到了很多游戏服务器开发技术,参与过几个不同架构的服务器开发,就随便聊聊游戏服务器开发需要的技术.(以下所指游戏服务器更偏向于手游,因为我对端游和页游开发接触并不多) 一.聊聊服务器开发有哪些东西要考虑. 1.开发语言的选择: 工欲善其事,必先利其器,选择一门适合的开发语法对后期开发有着事半功倍的作用. 业界主要的是c/c++ + Python/lua模式做游戏服务器.c/c++做网络通讯数据传输,python/lua做业务逻辑.这样既保持