编写程序时如何判断代码的时间复杂度与空间复杂度?
代码运行效率与内存占用的判断经验
我平时判断代码的效率和内存问题,基本是长期开发+对底层逻辑熟悉之后的条件反射,不是什么玄学直觉,核心还是围绕时间/空间复杂度、运行时特性、硬件开销这几个维度来的,除了循环嵌套之外,常见的判断依据有这些:
运行耗时相关的参考点
- 隐式的高复杂度操作嵌套:看起来只有一层循环,但循环内部调用了O(n)或更高复杂度的内置方法,比如在循环里反复执行数组的
indexOf()、列表的sort(),本质上相当于隐式写了两层循环,总复杂度直接升到O(n²),数据量上来之后耗时会暴涨。 - 无批处理的高频IO/网络操作:IO(磁盘读写、数据库查询、接口调用)的开销是普通CPU运算的几万到几十万倍,循环里单次查库、单次写文件,哪怕每次处理的数据量很小,累计耗时也会比批量处理高上百倍。
- 重复的冗余计算:把不需要动态更新的计算逻辑放在循环内部反复执行,比如循环条件里每次都计算固定数组的长度,或者反复执行加密、序列化、正则匹配这类重计算逻辑,却不提前缓存计算结果,累计开销会非常可观。
- 频繁的小对象创建销毁:在带GC的语言(Java、Go、C#等)里,循环内反复创建临时小对象,会触发频繁的GC扫描和回收,很多时候GC停顿的耗时会远高于业务逻辑本身的执行时间。
- 错误的数据结构选型:需要高频按key查询的场景放着O(1)的哈希表不用,非要用数组遍历匹配;需要频繁增删的场景放着链表不用,非要用数组移位,这类选型错误带来的耗时提升比循环嵌套还要夸张。
内存占用相关的参考点
- 大对象全量加载:处理GB级的文件、数据集的时候,不做流式分片读取,直接一次性把全量数据读进内存,瞬间就能吃掉数倍于数据本身大小的内存,还会产生大量内存碎片。
- 无界集合只增不删:用全局哈希表、列表做缓存或者数据暂存的时候,没有设置过期淘汰、容量上限规则,程序运行时间越长,占用的内存就越高,最后直接触发OOM。
- 过度的对象包装:明明可以用基础类型(比如int、long)存储的数值,非要用包装类型(Integer、Long),单个数据的内存占用直接翻2~3倍,百万级以上的数据量下,额外占用的内存会达到数百MB甚至GB级。
- 无意义的深拷贝:不需要修改原对象的场景下反复做全量深拷贝,每拷贝一次就多占一份和原对象大小相同的内存,大对象场景下很容易直接把内存占满。
内容的提问来源于stack exchange,提问作者KrazyKoder67
相关产品推荐
相关产品推荐

