代码效率优化方法论

代码效率优化方法论

  • 复杂度:如何衡量程序运行的效率
  • 数据结构:将“昂贵”的时间复杂度转换成“廉价”的空间复杂度

复杂度:如何衡量程序运行的效率

  • 复杂度是什么
    • 复杂度是衡量代码运行效率的重要的度量因素。在介绍复杂度之前,有必要先看一下复杂度和计算机实际任务处理效率的关系,从而了解降低复杂度的必要性。
    • 计算机通过一个个程序去执行计算任务,也就是对输入数据进行加工处理,并最终得到结果的过程。每个程序都是由代码构成的
  • 怎么衡量复杂度
    • 实际衡量时,我们通常会围绕以下2 个维度进行。首先,这段代码消耗的资源是什么。一般而言,代码执行过程中会消耗计算时间和计算空间,那需要衡量的就是时间复杂度和空间复杂度。
    • 例子:某个十字路口没有建立立交桥时,所有车辆通过红绿灯分批次行驶通过。当大量汽车同时过路口的时候,就会分别消耗大家的时间。但建了立交桥之后,所有车辆都可以同时通过了,因为立交桥的存在,等于是消耗了空间资源,来换取了时间资源。
      代码效率优化方法论_第1张图片
  • 这段代码对于资源的消耗是多少
    • 我们不会关注这段代码对于资源消耗的绝对量,因为不管是时间还是空间,它们的消耗程度都与输入的数据量高度相关,输入数据少时消耗自然就少。为了更客观地衡量消耗程度,我们通常会关注时间或者空间消耗量与输入数据量之间的关系。
  • 复杂度是一个关于输入数据量 n 的函数
    • 假设你的代码复杂度是 f(n),那么就用个大写字母 O 和括号,把 f(n) 括起来就可以了,即 O(f(n))。例如,O(n) 表示的是,复杂度与计算实例的个数 n 线性相关;O(logn) 表示的是,复杂度与计算实例的个数 n 对数相关。
  • 线型相关解释:在向量空间V的一组向量A: 在这里插入图片描述,如果存在不全为零的数 k1, k2, ···,km , 使
    在这里插入图片描述
    则称向量组A是线性相关的 ,否则数 k1, k2, ···,km全为0时,称它是线性无关。
    由此定义看出 在这里插入图片描述是否线性相关,就看是否存在一组不全为零的数 k1, k2, ···,km使得上式成立。
    即是在这里插入图片描述看这个齐次线性方程组是否存在非零解,将其系数矩阵化为最简形矩阵,即可求解。此外,当这个齐次线性方程组的系数矩阵是一个方阵时,这个系数矩阵存在行列式为0,即有非零解,从而在这里插入图片描述 线性相关。
  • 对数:如果a的x次方等于N(a>0,且a≠1),那么数x叫做以a为底N的对数(logarithm),记作x=log_a N。其中,a叫做对数的底数,N叫做真数
  • 时间复杂度与代码结构的关系
    • 一个顺序结构的代码,时间复杂度是 O(1)。
    • 二分查找,或者更通用地说是采用分而治之的二分策略,时间复杂
    • 度都是 O(logn)。这个我们会在后续课程讲到。
    • 一个简单的 for 循环,时间复杂度是 O(n)。
    • 两个顺序执行的 for 循环,时间复杂度是 O(n)+O(n)=O(2n),其实也是 O(n)。
    • 两个嵌套的 for 循环,时间复杂度是 O(n²)。

复杂度通常包括时间复杂度和空间复杂度。在具体计算复杂度时需要注意以下几点。

它与具体的常系数无关,O(n) 和 O(2n) 表示的是同样的复杂度。
复杂度相加的时候,选择高者作为结果,也就是说 O(n²)+O(n) 和 O(n²) 表示的是同样的复杂度。
O(1) 也是表示一个特殊复杂度,即任务与算例个数 n 无关。
复杂度细分为时间复杂度和空间复杂度,其中时间复杂度与代码的结构设计高度相关;空间复杂度与代码中数据结构的选择高度相关。会计算一段代码的时间复杂度和空间复杂度,是工程师的基本功。

数据结构:将“昂贵”的时间复杂度转换成“廉价”的空间复杂度

  • 第一步,暴力解法。在没有任何时间、空间约束下,完成代码任务的开发。
  • 第二步,无效操作处理。将代码中的无效计算、无效存储剔除,降低时间或空间复杂度。
  • 第三步,时空转换。设计合理数据结构,完成时间复杂度向空间复杂度的转移。

你可能感兴趣的:(数据结构与算法)