当前位置: 首页 > news >正文

时间复杂度与空间复杂度分析

作为开发人员,我们都希望在完成功能的基础上让代码运行的更快、更省空间,那如何衡量编写的代码是否更有效率,这就需要我们学会如何分析代码时间复杂度和空间复杂度.

什么是复杂度分析

执行时间和占用空间是代码性能的2个评判标准,我们分别用时间复杂度和空间复杂度去描述这2个标准,二者统称复杂度,复杂度描述的是算法执行时间(或占用空间)随数据规模的增长关系.

为什么需要复杂度分析

有人可能想问我代码运行一下不就知道他执行多长时间了吗,为什么还需要复杂度分析,确实你能够通过这种方法评估出代码的执行效率,但是这样会有一些局限性.

1.测试结果太过于依赖测试环境
同一段代码在不同处理器的机器上运行结果是显然不一样的,这时就不知道应该参考哪个测试结果.
2.测试结果受到数据规模的影响很大
两段不同的代码在数据量比较小的时候可能相差甚微,无法真实反映代码的性能问题.

所以我们需要一个不依赖测试环境同时也不需要有具体的测试数据就能粗略的估计代码的执行效率的方法,也就是复杂度分析.

如何进行复杂度分析

大O复杂度表示法
先看一段代码,求1,2,3...n的累加和

int calc(int n) {
  int sum = 0;  //第一行
  for(int i = 1; i <=n; i++) {
    sum = sum + i;
  }
  return sum;
}

我们来评估一下这段代码的执行时间,假设每行执行的时间一样,为row_time.第1行需要一个row_time的执行时间,第2,3行分别执行了n次,所以需要2n*row_time的执行时间,所以这段代码加起来总共的执行时间为(2n+1)*row_time,虽然我们并不知道row_time的具体时间,但我们发现代码的总执行时间T(n)与代码的执行次数n成正比.我们可以用公式来表示

T(n) = O(f(n))

T(n)代表代码的总执行时间,f(n)代表代码的执行次数,O代表T(n)与f(n)成正比.所以上面的例子中,T(n) = O(2n+1),我们可以看出大O时间复杂度表示代码执行时间随数据规模的变化趋势,我们简称为时间复杂度.

当n很大时,公式中的常量,系数都可以忽略不计,并不会对变化趋势有太大影响,我们只需记下一个最大量级即可,那么刚刚的例子最后就可以记为T(n) = O(n)

那以后的代码如何去分析其时间复杂度呢,我们有以下法则:
1.看代码执行次数最多的一段,比如循环
2.多段代码取最大量级,比如单循环和多重循环,应取多重循环的复杂度
3.嵌套代码复杂度等于嵌套内外代码复杂度的乘积,比如递归和多重循环等

平时我们有一些常用的复杂度级别,比如O(1) (常数阶)、O(logn) (对数阶)、O(n) (线性阶)、O(nlogn) (线性对数阶)、O(n²) (平方阶)

了解了时间复杂度,那么空间复杂度也不难理解了,时间复杂度表示的是算法执行时间随数据规模增长的变化关系,那空间复杂度则表示的是算法存储空间随数据规模增长的变化关系.

总结

复杂度用来分析算法执行效率与数据规模增长的变化关系,越高阶复杂度的的算法执行效率也就越低,上面列举的复杂度级别从低到高分别为O(1)、O(logn)、O(n)、O(nlogn)、O(n²).

相关文章:

  • 面试必备指南:你的系统如何支撑高并发?
  • [学习笔记]虚树
  • Iterator 和 for...of 循环
  • SharePoint:如何使用PowerShell批量删除名称以XXX开始的List?
  • Kafka之与Spring集成
  • python 模块一览
  • 《流浪地球》:一个程序员用代码拯救了世界,真硬核!
  • 500位软件开发工程师的声音:微服务和CI/CD依旧是最爱
  • 机器学习进阶-图像形态学操作-膨胀操作 1.cv2.dilate(进行膨胀操作)
  • 用Python写一份独特的元宵节祝福
  • Java开源诊断工具 Arthas 发布v3.1.0
  • 汇编语言第一章检测题
  • 无法打开外网ip链接
  • vue 组件通信
  • vue 配置sass、scss全局变量
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Angularjs之国际化
  • Koa2 之文件上传下载
  • LeetCode算法系列_0891_子序列宽度之和
  • Mysql数据库的条件查询语句
  • TypeScript实现数据结构(一)栈,队列,链表
  • Vim Clutch | 面向脚踏板编程……
  • 近期前端发展计划
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #define、const、typedef的差别
  • #if 1...#endif
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $jQuery 重写Alert样式方法
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (13):Silverlight 2 数据与通信之WebRequest
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (八)Flask之app.route装饰器函数的参数
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)spring boot车辆管理系统 毕业设计 031034
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (原)Matlab的svmtrain和svmclassify
  • (转)fock函数详解
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .Net 4.0并行库实用性演练
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET CORE Aws S3 使用
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .NET正则基础之——正则委托
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • .ui文件相关
  • @ModelAttribute注解使用