复杂度分析(上)如何分析统计算法的执行效率和资源消耗

一、什么是复杂度分析?

  1. 数据结构和算法解决是“如何让计算机更快时间、更省空间的解决问题”。
  2. 因此需从执行时间占用空间两个维度来评估数据结构和算法的性能
  3. 分别用时间复杂度空间复杂度两个概念来描述性能问题,二者统称为复杂度。
  4. 复杂度描述的是算法执行时间(或占用空间)数据规模增长关系

二、为什么要进行复杂度分析?

2.1 事后统计法

2.2.1 概念

  通过运行代码跑,统计、监控,得到算法执行的时间和占用的内存大小。

2.2.2 劣势

  1. 测试结果非常依赖测试环境。测试环境中硬件的不同会对测试结果有很大的影响。
  2. 测试结果受数据规模的影响很大。

2.2 复杂度分析

  1. 和性能测试相比,复杂度分析有不依赖执行环境、成本低、效率高、易操作、指导性强的特点。
  2. 掌握复杂度分析,将能编写出性能更优的代码,有利于降低系统开发和维护成本。

三、如何进行复杂度分析?

3.1.大O表示法

  1)来源
  算法的执行时间与每行代码的执行次数成正比,用T(n) = O(f(n))表示,其中T(n)表示算法执行总时间,f(n)表示每行代码执行总次数,而n往往表示数据的规模
  2)特点
  以时间复杂度为例,由于时间复杂度描述的是算法执行时间与数据规模的增长变化趋势,所以常量阶、低阶以及系数实际上对这种增长趋势不产决定性影响,所以在做时间复杂度分析时忽略这些项。

3.2.复杂度分析法则

  1. 单段代码看高频:在单段代码中只关注循环执行次数最多的一段代码。比如循环。
  2. 多段代码取最大:在多段代码中只关注循环执行次数最多的一段代码,总复杂度等于量级最大的那段代码的复杂度。比如一段代码中有单循环和多重循环,那么取多重循环的复杂度。
  3. 嵌套代码求乘积:比如递归、多重循环等。
  4. 多个规模求加法:代码的复杂度由两个数据的规模来决定。比如方法有两个参数控制两个循环的次数,那么这时就取二者复杂度相加。

四、常用的时间复杂度级别?

4.1 多项式阶

  随着数据规模的增长,算法的执行时间和空间占用,按照多项式的比例增长。包括,
  O(1)(常数阶)、O(logn)(对数阶)、O(n)(线性阶)、O(nlogn)(线性对数阶)、O(n^2)(平方阶)、O(n^3)(立方阶)

4.2 非多项式阶

  随着数据规模的增长,算法的执行时间和空间占用暴增,这类算法性能极差。包括,
  O(2^n)(指数阶)、O(n!)(阶乘阶)

五、常用的空间复杂度级别?

  空间复杂度全称就是渐进空间复杂度,表示算法的存储空间与数据规模之间的增长关系。 

  常见的空间复杂度就是 O(1)、O(n)、O(n2 ),像 O(logn)、O(nlogn) 这样的对数阶复杂度平时都用不到。而且,空间复杂度分析比时间复杂度分析要简单很多。

六. 总结

  渐进时间,空间复杂度分析为我们提供了一个很好的理论分析的方向,并且它是宿主平台无关的,能够让我们对我们的程序或算法有一个大致的认识,让我们知道,比如在最坏的情况下程序的执行效率如何,同时也为我们交流提供了一个不错的桥梁,我们可以说,算法1的时间复杂度是O(n),算法2的时间复杂度是O(logN),这样我们立刻就对不同的算法有了一个“效率”上的感性认识。

  当然,渐进式时间,空间复杂度分析只是一个理论模型,只能提供给粗略的估计分析,我们不能直接断定就觉得O(logN)的算法一定优于O(n), 针对不同的宿主环境,不同的数据集,不同的数据量的大小,在实际应用上面可能真正的性能会不同,个人觉得,针对不同的实际情况,进而进行一定的性能基准测试是很有必要的,比如在统一一批手机上(同样的硬件,系统等等)进行横向基准测试,进而选择适合特定应用场景下的最有算法。

  综上所述,渐进式时间,空间复杂度分析与性能基准测试并不冲突,而是相辅相成的。但是一个低阶的时间复杂度程序有极大的可能性会优于一个高阶的时间复杂度程序,所以在实际编程中,时刻关心理论时间,空间度模型是有助于产出效率高的程序的,同时,因为渐进式时间,空间复杂度分析只是提供一个粗略的分析模型,因此也不会浪费太多时间,重点在于在编程时,要具有这种复杂度分析的思维。

猜你喜欢

转载自www.cnblogs.com/virgosnail/p/9829537.html
今日推荐