您的位置:首页 > 其它

程序性能分析

2017-01-07 17:55 183 查看
对一个程序来说,正确性是最重要的。若程序不能完成指定的任务,它就没有什么用处。然而,程序即使能完成任务,但资源消耗过大,那它也没有什么意义。

本文旨在概述程序性能分析的一些概念、两个简单的分析方法和渐进记法

1. 程序性能分析的一些概念

程序性能:指运行一个程序所需要的内存和时间的多少。用两种方法来确定程序的性能,分析方法和试验方法。在性能分析的时候,采用分析方法;在性能测量的时候采用试验方法。
空间复杂度:程序运行是所需要的内存的大小。由指令空间(代码段)、数据空间(初始化及未初始化的全局变量和静态变量)和环境栈空间(局部变量和自动变量)构成。影响空间复杂度的因素有很多,如目标计算机、编译器、程序的时间算法等。
时间复杂度:程序运行所需要的时间,包括编译时间和运行时间。
2. 分析方法

影响程序性能的因素很多,在性能分析时并不能给出精确的结论。不过,程序要处理的问题都有一些特征,这些特征包含着可以决定程序性能的因素,如输入和输出的规模、相关数的大小等。一般来说,我们的选择仅限于输入输出规模,记实力特征为n。

空间复杂度分析
空间复杂度 = C + Sp(n)

其中,C为固定部分,它与实力特征没有关系,包括代码和全局变量和静态变量;Sp(n)为可变部分,依赖于实力特征n,我们主要分析这一部分。

以n的阶乘函数来举例说明一下,假设int类型占用4个字节:

//迭代法
int factorial_iteration(int n)    //参数n,4个字节
{
int result = 1;    //result,4个字节
for(int i = n; i > 1; i--)    //i,4个字节
result *= i;

return result;     //返回地址,指针类型4个字节
}

//递归法
int factorial_recursion(int n)    //参数n,4个字节
{
if(n > 1)
return n * factorial_recursion(n - 1);
else
return 1;    //返回地址,指针类型4个字节
}


迭代法:Sp(n) = 4 + 4 + 4+ 4 = 16 (字节)

递归法:Sp(n) = (4 + 4) * max{n, 1} = 8max{n, 1} (字节)

所以说,迭代法阶乘空间复杂度为常量,递归法阶乘的空间复杂度随n线性增长。

时间复杂度分析
编译时间与实力特征无关,所以我们只关心程序运行时间,Tp(n)。

有两个较容易的方法: 1) 计算关键操作的执行次数; 2) 确定程序总的步数。这里不详述如何确定关键操作和程序的一步,提示一点:关键操作一般是比较耗时的操作,程序的一步必须独立于实力特征。

还是以阶乘函数为例,这里假设n > 0:

迭代法 :若按照方法1,将result *= i; 视为关键操作,那么Tp(n) = n - 1 ;

若按照方法2,如下:

程序操作包含步数s/e频率f总的步数
int result = 1;111
for(int i = n; i > 1; i--)1nn
    result *= i;1n - 1n - 1
return result;111
  Tp(n) =2n + 1
可见方法1忽略掉了部分步骤,如result定义、for循环条件判断。

递归法:按照方法2:

程序操作包含步数s/e频率f总的步数
if(n > 1)1nn
return *;1nn
  Tp(n) =2n
所以,两种阶乘算法的函数的时间复杂度都随实力特征n线性增长。

3. 渐进记法

定义:令p(n)和q(n)是两个非负函数。称p(n)渐进地大于q(n),当且仅当n趋于无穷大时,q(n)/p(n) = 0;称q(n)渐进地小于p(n);称p(n)渐进地等于q(n),当且仅当任何一个都不渐进地大于另一个。

记法:

f(n) = O(g(n)):代表f(n)渐进小于或等于g(n);
f(n) =
Ω(g(n)):代表f(n)渐进大于或等于g(n);
f(n) =
Θ(g(n)):代表f(n)渐进等于g(n);  

f(n) = o(g(n)):代表f(n)渐进小于g(n);
在步数分析中经常出现的项有:1 < logn < n < nlogn < n^2 < n^3 < 2^n < n!

上述阶乘函数的时间复杂度Tp(n) =
Θ(n)。
在程序性能分析中,通常会涉及到最好、最坏和平均操作计数。前两者比较简单,平均操作计数要用到概率的知识,比较复杂。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  性能