【C++数据结构】程序性能分析

news2025/7/19 7:46:25

程序性能分析

2.1 什么是程序性能

程序性能:所谓程序性能(performance of a program)是指运行这个程序所需要的内存和时间的多少。

性能分析:在性能分析(performance analysis)时,采用分析方法。

性能测量:在性能测量(performance measurement)时,使用实验方法。

程序的空间复杂度:(space complexity)是指该程序的运行所需内存的大小。

  • 一个程序要运行在一个多用户计算机系统中,需要指明该程序所需内存的大小。
  • 在任何一个计算机系统上运行程序,都需要知道是否有足够的内存可以用来运行该程序。
  • 一个问题可能有若干个解决方案,它们对内存的需求各不相同。
  • 利用空间复杂度,我们可以估算一个程序所能解决的问题最大可以是什么规模。

时间复杂度:(time complexity)是指运行程序所需要的时间。

  • 有些计算机需要用户提供程序运行时间的上限,一旦达到这个上限,程序将被强制结束。
  • 正在开发的程序可能需要一个令人满意的实时响应。

2.2 空间复杂度

2.2.1 空间复杂度的组成

(1)指令空间(instruction space)
指令空间是指编译之后的程序指令所需要的存储空间。

(2)数据空间(data space)
数据空间是指所有常量和变量值所需要的存储空间。它由两个部分构成:

  • 常量和简单变量所需要的存储空间。
  • 动态数组和动态类实例等动态对象所需要的空间。

(3)环境栈空间(environment stack space)
环境栈用来保存暂停的函数和方法在恢复运行时所需要的信息。(保存现场)

2.2.2 指令空间

指令空间的数量取决于如下因素:

  • 把程序转换成机器代码的编译器。
  • 在编译时的编译器选项。
  • 目标计算机的配置。

覆盖选项:编译器的覆盖选项也可以显著地减少程序空间。在覆盖模式下,空间仅分配给当前正在执行的程序模块。调用一个新模块需要从磁盘或其他设备中读取,新模块的代码将覆盖原模块的代码。因此,程序所需要的空间便是最大模块所需要的空间,而不是所有模块所需要的空间之和。

2.2.3 数据空间

在这里插入图片描述

一个结构变量的空间大小是每个结构成员所需的空间大小之和。类似的,一个数组的空间大小是数组的长度乘以一个数组元素的空间大小。

2.2.4 环境栈空间

下面的数据将被保存在环境栈中:

  • 返回地址。
  • 正在调用的函数的所有局部变量的值以及形式参数的值(仅对递归函数而言)。

值得注意的是,有些编译器,不论对递归函数还是非递归函数,在函数调用时,都会保留局部变量和形参的值,而有些编译器仅对递归函数才会如此。因此,实际使用的编译器将影响环境栈所需空间的大小。

递归函数所需要的栈空间通常称为递归栈空间(recursion stack space)。它的大小依赖于局部变量和形式参数所需要的空间,依赖于递归的最大深度(即嵌套递归调用的最大层次)。

可以把一个程序所需要的空间分成两部分:

  • 固定部分:它独立于实例特征。这一部分通常包括指令空间(即代码空间)、简单变量空间和常量空间等。
  • 可变部分:它由动态分配空间构成和递归栈空间构成。前者在某种程度上依赖实例特征,而后者主要依赖实例特征。

任意程序P所需要的空间可以表示为:
c + S p ( 实 例 特 征 ) c+S_p(实例特征) c+Sp()
其中c是一个常量,表示空间需求的固定部分,S_p表示空间需求的可变部分。要精确地分析空间性能,还要考虑在编译期间所产生的临时变量所需要的空间 。

举例

//程序1-31 累加数组元素a[0:n-1]的递归代码
template<class T>
T rSum(T a[], int n)
{//返回数组元素a[0:n-1]的和
    if(n > 0return rSum(a,n-1+ a[n-1];
    return O;
}

例2-4 考虑程序1-31的函数rSum。假定实例特征为n。递归栈空间包括形式参数a和n以及返回地址的空间。对于a,需要保留一个指针(4字节),而对于n则需要保留一个int类型的值(也是4字节)。如果假定返回地址也是4字节,那么每一次递归调用需要12字节的栈空间。因为递归深度是n+1,所以递归栈空间需要12(n+1)字节。因此S_rsum(n)= 12(n+1)。(此处求的是可变部分)

2.3 时间复杂度

2.3.1 时间复杂度的组成

一个程序P所需要的时间是编译时间运行时间之和。编译时间与实例特征无关。一个编译过的程序可以运行若干次而不需要重新编译。因此我们将主要关注程序的运行时间。运行时间通常用以下式子来表示:
t p ( 实 例 特 征 ) t_p(实例特征) tp

2.3.2 操作计数

估算一个程序或函数的时间复杂度,一种方法是选择一种或多种关键操作,例如加、乘、比较等,然后确定每一种操作的执行次数。使用这种方法成功与否取决于是否能够找到耗时最大的操作。

//程序2-4 利用Horner法则的多项式计算
template<class T>
T horner(T coeff[], int n, const T&x)		
{//计算n阶多项式在点x处的值,系数为coeff[0:n]
	T value = coeff[n];
	for (int i= 1; i <= n; i++)
		value = value * x + coeff[n - i]; 
	return value;
}

程序2-4的时间复杂度是n次加法和n次乘法,所以其运行时间近似为:
加 法 运 行 时 间 ∗ n + 乘 法 运 行 时 间 ∗ n 加法运行时间*n+乘法运行时间*n n+n

2.3.3最好、最坏和平均操作计数

//程序2-1 顺序查找
template<class T>
int sequentialSearch(T a[], int n, const T& x)
{//在数组 a[0:n-1]中查找元素x
//如果找到,则返回该元素的位置,否则返回-1
	int i;
	for(i = 0;i <n && a[i] != x;i++);
	if(i = n) return -1;
	else return i;
}

对程序2-1的顺序查找函数,我们要确定x与数组元素之间的比较次数。我们自然地把n作为实例特征。可是比较次数不是由n唯一确定的。例如,如果n=100 且 x=a[0],那么仅需要一次比较。如果x不在数组中,则需要100次比较。若x属于a,则查找成功,否则查找不成功。查找不成功时的比较次数都是n。如果查找成功,则最少比较1次,最多比较n次。为了计算平均比较次数,我们假设所有数组元素都不相同,但每个元素被查找的概率都相同。这时,查找成功的平均比较次数如下:
1 n ∑ i = 0 n i = n + 1 2 \frac{1}{n}\sum_{i=0}^ni=\frac{n+1}{2} n1i=0ni=2n+1

2.3.4 步数

2.3.4.1 定义

用操作计数方法来估算程序的时间复杂度时,都是针对选定的操作,而忽视了其他的操作。在步数(step-count)方法中,将对程序/函数的所有操作部分都进行统计。与操作计数一样,步数也是实例特征的函数。任何一个具体的实例都可能有若干个特征(例如输入个数、输出个数、输入和输出的大小),但是步数是特征的一个子集的函数。通常我们选择的特征都是我们感兴趣的特征。例如,如果我们想知道,程序的运行时间(即时间复杂度)如何随着输入个数的增加而增加,那么就把步数仅看成是输入个数的函数。

因此,要确定一个程序的步数,必须先确定所要采用的实例特征。

**一步(a step)**是一个计算单位,它独立于所选定的实例特征。

**定义2-1[程序步]**一个程序步(a program step)可以大概地定义为一个语法或语义上的程序片段,该片段的执行时间独立于实例特征。一个程序步所表示的计算量可能与另一个程序步所表示的计算量不同。

2.3.4.2 计算程序或函数的步数

方法1

为了确定一个程序或函数的步数,可以创建一个初始值为0的全局变量stepCount。把这个变量的增值语句嵌入原程序,每当原程序或原函数的一条语句执行一次,stepCount的值就增1。当程序或函数运行结束时,stepCount的值便是程序步数。

分析递归函数的步数时,可以得到递推方程

//程序2-18 计算程序1-31的程序步数
template<class T>
T rSum(T a[]int n)
{//返回数组元素a[0:n-1]的和
    stepCount++;//if 语句是一个程序步
    if(n > 0)
    {
   		stepCount++;//return 语句和调用语句是一个程序步
    	return rSum(a,n-l)+ a[n-1];
    }    	
    //return 语句是一个程序步
    stepCount++;
	return 0;
}

在这里插入图片描述

方法2

如果不想嵌入stepCount的增值语句,可以建立一张表,列出每条语句的总步数。为此,首先要确定每条语句每次执行所需要的步数(s/e,steps per execution),以及该语句总的执行次数,即频率(frequency)。然后把这两个数据相乘,便得到每条语句的总步数。最后把所有语句的总步数加在一起便得到整个程序的步数。这种方法称为剖析法(profiling)
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ceph命令应用

记录&#xff1a;337 场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;在ceph集群中&#xff0c;使用ceph命令查看ceph集群信息&#xff0c;以及mon、mgr、mds、osd、rgw等组件信息。 版本&#xff1a; 操作系统&#xff1a;CentOS 7.9 ceph版本&#xff1a;ceph-13.2.…

JavaSE从基础到入门:抽象类和接口

1.抽象类 1.抽象类的概念 在面向对象的概念中&#xff0c;所有的对象都是通过类来描绘的&#xff0c;但是反过来&#xff0c;并不是所有的类都是用来描绘对象的&#xff0c;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类。 比如&#x…

Android App开发实战项目之仿喜马拉雅的听说书App实现(超详细 附源码)

需要全部源码请点赞关注收藏后评论区留下QQ~~~ 一、需求分析 用户不仅能在平台上收听音频&#xff0c;还能成为内容创作者&#xff0c;总之长音频分享平台需要满足两种角色的使用&#xff1a;一种是作为内容创作者发布自己的音频&#xff0c;另一种是作为用户欣赏平台上的已有…

java项目-第162期ssm电影售票系统_ssm毕业设计_计算机毕业设计

java项目-第162期ssm电影售票系统_ssm毕业设计_计算机毕业设计 【源码请到资源专栏下载】 今天分享的项目是《ssm电影售票系统》 该项目分为2个角色&#xff0c;管理员、用户。 用户可以浏览前台电影信息、新片预告&#xff0c;并且可以进行影片预订、 座位选座。用户登录后台…

谈数据库查询涉及的存储效率

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu) 参考&#xff1a;https://blog.csdn.net/Sword52888/article/details/125352635 11月马上也进入尾声了&#xff1b;紧接着的12月&#xff0c;新年也就不远了… 今年对数据查询做了许多的分析、测试、修改、验证&#xf…

centOS 7 Install Harbor(私有镜像仓库)V2

一、安装docker环境 略. 二、下载离线安装包 下载地址https://github.com/goharbor/harbor/releases/download/v1.10.15/harbor-offline-installer-v1.10.15.tgz三、拷贝到服务器/application #解压 tar -xvf harbor-online-installer-v1.2.0.tgz #生成证书 cd /applicati…

【计算机毕业设计】45.医院挂号系统

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 伴随着社会以及科学技术的发展&#xff0c;互联网已经渗透在人们的身边&#xff0c;网络慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;管理系统这一名词已不陌生&…

【计算机毕业设计】41.航空订票系统

摘 要 网络的广泛应用给生活带来了十分的便利。所以把航空订票与现在网络相结合&#xff0c;利用JSP技术建设航空订票系统&#xff0c;实现航空订票的信息化。则对于进一步提高航班公司的发展&#xff0c;丰富航空订票经验能起到不少的促进作用。 航空订票系统能够通过互联网…

数字信号处理-10-并行FIR滤波器MATLAB与FPGA实现

前言 本文介绍了设计滤波器的FPGA实现步骤&#xff0c;并结合杜勇老师的书籍中的并行FIR滤波器部分进行一步步实现硬件设计&#xff0c;对书中的架构做了复现以及解读&#xff0c;并进行了仿真验证。 并行FIR滤波器FPGA实现 FIR滤波器的结构形式时&#xff0c;介绍了直接型、…

23. [Python GUI] PyQt5中的模型与视图框架-抽象视图基类QAbstractItemView

PyQt5的抽象视图基类QAbstractItemView 一、QAbstractItemView的基本概念 QAbstractItemView 类继承自 QAbstractScrollArea&#xff0c;后者又继承自 QFrame&#xff0c;该类是 Qt 所有视图类的基类&#xff0c; Qt 的所有视图都需要子类化该类。注意&#xff1a;该类是抽象…

Linux系统编程(四)——signal信号处理

目录 0x01 信号 0x02 信号相关的函数 一、kill函数 二、alarm()函数 三、setitimer() 四、signal() 0x03 信号集 一、信号集的处理过程 ​编辑 二、关于信号集处理的函数 0x04 内核实现信号捕捉的过程 0x05 SIGCHLD信号 0x01 信号 信号是Linux进程间通信的最古老的…

通过FNN算法进行特征组合的商品推荐详细教程 有代码+数据

案例知识点 推荐系统任务描述:通过用户的历史行为(比如浏览记录、购买记录等等)准确的预测出用户未来的行为;好的推荐系统不仅如此,而且能够拓展用户的视野,帮助他们发现可能感兴趣的却不容易发现的item;同时将埋没在长尾中的好商品推荐给可能感兴趣的用户。CTR表示Clic…

【2021 MCM】 Problem A: Fungi by 2100454

【2021 MCM】 Problem A: Fungi by 2100454 文章目录【2021 MCM】 Problem A: Fungi by 2100454一、题目分析1.1 问题总述1.2 具体任务1.3 需要提交的内容二、论文解读2.1 摘要2.2 目录2.3 简介2.4 假设2.5 缩写和定义2.6 The GAME Model2.6.1 Gause’s Model for Predicting F…

防火墙基本概念

防火墙是一款具有安全防护功能的网络设备&#xff0c;保护一个网络区域避免另一个网络区域的攻击和入侵。 物理防火墙&#xff08;物理设备&#xff09;、软件防火墙&#xff08;Windows自带firewall&#xff09; 其本职工作是隔离网络 基本功能 会话管理内网安全管控入侵…

[附源码]java毕业设计中医药系统论文2022

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

痞子衡嵌入式:MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制

大家好&#xff0c;我是痞子衡&#xff0c;是正经搞技术的痞子。今天痞子衡给大家分享的是MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制。 痞子衡之前写过一篇文章 《MCUXpresso IDE下工程链接文件配置管理与自动生成机制》&#xff0c;这篇文章介绍了 MCUXpresso ID…

网页前端知识汇总(三)——网页前端利用二维码插件qrcode生成在线二维码

最近几年二维码的广泛应用&#xff0c;方便了很多行业&#xff0c;如支付宝&#xff0c;微信&#xff0c;小程序扫码之类的&#xff0c;这个在二十年前&#xff0c;想都不敢想这么方便&#xff0c;那时候有书刊编码扫一扫都感觉是高科技了&#xff0c;如今&#xff0c;二维码的…

RNA-seq 详细教程:实验设计(2)

学习目标 了解设置重复对于 RNA-seq 分析的重要性了解生物重复次数、测序深度和鉴定到的差异表达基因之间的关系了解如何设计RNA-seq 实验&#xff0c;以避免批次效应1. 注意事项 了解 RNA 提取和 RNA-seq 文库制备实验过程中的步骤&#xff0c;有助于设计 RNA-seq 实验&#x…

PyTorch学习笔记-常用函数与数据加载

1. PyTorch常用函数 &#xff08;1&#xff09;路径相关的函数 假设我们数据集的目录结构如下&#xff1a; 首先需要 import os&#xff0c;在 os 中常用的路径相关的函数有&#xff1a; os.listdir(path)&#xff1a;将 path 目录下的内容列成一个 list。os.path.join(path1…

cmake入门教程 跨平台项目构建工具cmake介绍

一.初识cmake 在介绍cmake之前&#xff0c;我们先来从工具一个个衍生出来&#xff0c;做过linux c/c编程的时候一般用过gcc指令或者makefile。我们先来介绍下 gcc&#xff08;GNU Compiler Collection&#xff09;将源文件编译&#xff08;Compile&#xff09;成可执行文件或…