第13话:算法的性能分析
2012-06-07 00:00
966 查看
算法的设计要注意效率,这里效率大都指算法的执行时间。一个用高级程序语言编写的程序在计算机上运行时所消耗的时间取决于下列因素:
算法采用的策略、方法。
编译产生的代码质量。
问题的输入规模。
机器执行指令的速度
第1条当然是箅法好坏的根本,第2条要由软件来支持,第4条要看硬件性能。也就是说,抛开这些与计算机硬件、软件有关的因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模。所谓问题输入规模是指输入量的多少。
比如计算从1加到100的值,有两种算法。
正如程序的注释中计数一样,第一种算法,执行了 1+ (n+1) +n+l次=2n+3次;而第二种算法,是 1+1+1=3次。
事实上两个算法的第一条和最后一条语句是一样的,所以我们关注的代码其实是中间的那部分,我们把循环看作一个整体,忽略头尾循环判断的开销,那么这两个算法其实就是n次与1次的差距。算法好坏显而易见。
再来看一个程序:
这个例子中,i从1到100,每次都要让j循环100次,而当中的x++和sum = sum + x;其实就是1+2+3+…+10000,也就是1002次,所以这个算法当中,循环部分的代码整体需要执行n2(忽略循环体头尾的开销)次。显然这个算法的执行次数对于同样的输入规模n = 100,要多于前面两种算法,这个算法的执行时间随着n的增加也将远远多于前面两个。
此时你会看到,测定运行时间最可靠的方法就是计算对运行时间有消耗的基本操作的执行次数。运行时间与这个计数成正比。
我们不关心编写程序所用的程序设计语言是什么,也不关心这些程序将跑在什么样的计算机中,我们只关心它所实现的算法。这样,不计那些循环索引的递增和循环终止条件、变量声明、打印结果等操作,最终,在分析程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤。
同样问题的输入规模是n,求和算法的第一种,求 1+2+…+n需要一段代码运行n次。那么这个问题的输入规模使得操作数量是f(n)=n,显然运行100次的同一段代码规模是运算10次的10倍。
而第二种,无论n为多少,运行次数都为1,即f(n) =1;第三种,运算100次是运算10次的100 倍。因为它是f(n) =n2。
我们可以这样认为,随着n值的越来越大,它们在时间效率上的差异也就越来越大。
第一话:你的数据结构怎么学的?
第二话:数据结构的历史与来由
第三话:关于数据结构的一些概念
第四话:数据的逻辑结构
第五话:数据的物理结构
第六话:关于数据类型
第七话:抽象数据类型ADT
第八话:补充数据结构基本概念的关系
第九话:数据结构与算法的关系
第10话:什么是算法?
第11话:算法的五个基本特征
第12话:什么样的算法才是好算法
第13话:算法的性能分析
第14话:如何计算算法的时间复杂度
第15话:算法的最坏情况与平均情况
第16话:算法的空间复杂度
本文地址:http://www.nowamagic.net/librarys/veda/detail/2193,欢迎访问原出处。
算法采用的策略、方法。
编译产生的代码质量。
问题的输入规模。
机器执行指令的速度
第1条当然是箅法好坏的根本,第2条要由软件来支持,第4条要看硬件性能。也就是说,抛开这些与计算机硬件、软件有关的因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模。所谓问题输入规模是指输入量的多少。
比如计算从1加到100的值,有两种算法。
#include "stdio.h" int main() { int i, sum = 0, n = 100; /* 执行1次 */ for( i = 1; i 上面是最常见的算法,再来看一下小时候高斯的算法:#include "stdio.h" int main() { int sum = 0, n = 100; /* 执行1次 */ sum = (1 + n) * n/2; /* 执行1次 */ printf("%d", sum); /* 执行1次 */ }
正如程序的注释中计数一样,第一种算法,执行了 1+ (n+1) +n+l次=2n+3次;而第二种算法,是 1+1+1=3次。
事实上两个算法的第一条和最后一条语句是一样的,所以我们关注的代码其实是中间的那部分,我们把循环看作一个整体,忽略头尾循环判断的开销,那么这两个算法其实就是n次与1次的差距。算法好坏显而易见。
再来看一个程序:
#include "stdio.h" int main() { int i, j, x = 0, sum = 0, n = 100; /* 执行1次 */ for( i = 1; i
这个例子中,i从1到100,每次都要让j循环100次,而当中的x++和sum = sum + x;其实就是1+2+3+…+10000,也就是1002次,所以这个算法当中,循环部分的代码整体需要执行n2(忽略循环体头尾的开销)次。显然这个算法的执行次数对于同样的输入规模n = 100,要多于前面两种算法,这个算法的执行时间随着n的增加也将远远多于前面两个。
此时你会看到,测定运行时间最可靠的方法就是计算对运行时间有消耗的基本操作的执行次数。运行时间与这个计数成正比。
我们不关心编写程序所用的程序设计语言是什么,也不关心这些程序将跑在什么样的计算机中,我们只关心它所实现的算法。这样,不计那些循环索引的递增和循环终止条件、变量声明、打印结果等操作,最终,在分析程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤。
同样问题的输入规模是n,求和算法的第一种,求 1+2+…+n需要一段代码运行n次。那么这个问题的输入规模使得操作数量是f(n)=n,显然运行100次的同一段代码规模是运算10次的10倍。
而第二种,无论n为多少,运行次数都为1,即f(n) =1;第三种,运算100次是运算10次的100 倍。因为它是f(n) =n2。
我们可以这样认为,随着n值的越来越大,它们在时间效率上的差异也就越来越大。
延伸阅读
此文章所在专题列表如下:第一话:你的数据结构怎么学的?
第二话:数据结构的历史与来由
第三话:关于数据结构的一些概念
第四话:数据的逻辑结构
第五话:数据的物理结构
第六话:关于数据类型
第七话:抽象数据类型ADT
第八话:补充数据结构基本概念的关系
第九话:数据结构与算法的关系
第10话:什么是算法?
第11话:算法的五个基本特征
第12话:什么样的算法才是好算法
第13话:算法的性能分析
第14话:如何计算算法的时间复杂度
第15话:算法的最坏情况与平均情况
第16话:算法的空间复杂度
本文地址:http://www.nowamagic.net/librarys/veda/detail/2193,欢迎访问原出处。
相关文章推荐
- TCP拥塞控制算法 优缺点 适用环境 性能分析
- 深度学习目标检测算法性能分析
- 算法的时间性能分析
- 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)
- Java之学习笔记(11)------------算法性能分析
- javascript 性能分析:算法和流程控制
- 【转载】TCP拥塞控制算法 优缺点 适用环境 性能分析
- 多种排序算法性能分析代码 C++
- TCP拥塞控制算法 优缺点 适用环境 性能分析
- 算法学习一:排序算法实现与算法性能分析
- 【机器学习】K均值算法 - 性能分析
- KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较
- 背景建模技术(二):BgsLibrary的框架、背景建模的37种算法性能分析、背景建模技术的挑战
- TCP拥塞控制算法 优缺点 适用环境 性能分析
- 算法分析(总结)排序算法性能及比较总结
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
- 背景建模技术(二):BgsLibrary的框架、背景建模的37种算法性能分析、背景建模技术的挑战
- Java遍历集合的几种方法分析(实现原理、算法性能、适用场合)
- 算法的时间性能分析
- TCP拥塞控制算法 优缺点 适用环境 性能分析