程序员在日常程序开发中经常有如下两个困惑:
- 我的程序会运行多长时间?
- 为什么我的程序会耗尽所有内存?
要回答这两个问题有时很困难,因为决定的因素挺多:机器的性能、需要处理的数据以及程序本省的算法是否较优等等,这些因素往往都需要进行大量的分析,在互联网上也能找到大量类似“xxx性能优化实践”的文章。
我们将试图采用科学的方法,使用数学分析为算法成本建立简洁的模型并使用实验数据验证这些模型。
1.科学的分析方法
回想一下小时候我们在学物理化学对自然问题的研究方法,一般需要经过以下过程:
- 细致地观察真实世界的特点,在观察时通过也伴随着测量和收集测量数据。
- 根据观察结果提出假设模型。
- 根据模型预测未来的事件。
- 继续观察并核实预测的准确性。
如此反复,直到预测和观察一致。
科学方法的两个原则
科学方法有两个原则:可重现和可证伪。
- 可重现能够保证别人也能够证明假设的真实性。
- 可证伪我们才能够确认某个假设是错误的,然后去修正它。
爱因斯坦说过一句话:“再多的实验也不一定能够证明我是对的,但只需要一个实验就能够证明我是错的。”就是这个道理,我们永远无法知道某个假设是绝对正确,因此我们只需要验证它和我们观察到的一致。
如何描述程序的运行时间
D.E.Knuth指出程序运行总时间主要和亮点有关:
- 执行每条语句耗时。
- 执行每条语句的频率。
第一点取决于计算机、编译器和操作系统,第二点取决于程序本身和输入。
算法性能分析我们并不需要像Knuth描述那样非常精确的了解程序的执行时间,一般我们会做近似计算处理,定性的通过分析了解算法执行的时间复杂度进而了解算法的性能。
2.观察与测量
和自然实验相比,观察程序的运行时间要简单太多,我们只需要Run,程序就开始运行了,通过记录开始和结束时间,就能回答一个本文一开头提的核心问题:我的程序运行需要多长时间。
主观上,程序的运行时间和问题的规模(即输入)有关,程序的运行时间随着问题的规模增长而增长,作为程序员,我们每次开发程序时都要问问自己程序随着问题规模增长增长有多快,好的程序能够控制程序运行时间,随着问题规模的增长程序运行时间增长不那么敏感不那么快!
另一个需要注意的是,精确测量程序运行时间很苦难,一般我们只需要程序运行时间的近似数据,根据近似数据得出程序随着问题规模N变化的函数T(N)。
下面,我们通过3数之和来分析测量过程,问题描述如下。
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意: