LeetCode 1860题:两段相似Python代码运行耗时差异原因咨询
两段LeetCode 1860代码的性能差异原因分析
我发现两段解决LeetCode 1860《Incremental Memory Leak》问题的Python代码逻辑相似、输出完全一致,但在对1-1000间的随机输入各运行100万次后,第一段耗时2.53秒,第二段耗时28.8秒,以下是具体原因分析:
第一段代码
def memLeak1(self, memory1: int, memory2: int): i = 1; while memory2 >= 0 and memory1 >= 0: if memory1 >= memory2: if memory1 >= i: memory1 -= i; else: break; else: if memory2 >= i: memory2 -= i; else: break; i += 1; return [i,memory1,memory2];
第二段代码(注:推测存在粘贴笔误,正确逻辑应将i += 1放入循环体内,否则输出无法与第一段一致)
def memLeak2(self, memory1: int, memory2: int): i = 1 while memory1 >= i or memory2 >= i: if memory1 >= memory2: memory1 -= i else: memory2 -= i i += 1 # 修正后位置 return [i, memory1, memory2]
核心性能差异原因
循环条件的判断开销差异
- 第一段的循环条件是
memory2 >= 0 and memory1 >= 0,由于代码逻辑保证内存值只会被减去不超过自身的正数,内存永远不会为负,这个条件等价于while True,每次判断仅需两次变量与常数0的比较,速度极快。 - 第二段的循环条件是
memory1 >= i or memory2 >= i,每次需要执行两次变量与变量i的比较,再进行一次或运算。变量间的比较开销远高于变量与常数的比较,且i不断递增,每次都要从局部变量中取值,进一步增加了判断耗时。
- 第一段的循环条件是
循环终止时机的判断逻辑
- 第一段在循环内部直接判断当前内存是否足够分配i,一旦不足立即
break终止循环,无需再执行下一轮循环条件判断。 - 第二段依赖循环条件本身来终止,每次循环都要先判断两个内存与i的大小关系,即使某次分配后已经无法继续分配,仍需完成一次完整的循环条件判断才能停止。
- 第一段在循环内部直接判断当前内存是否足够分配i,一旦不足立即
当运行次数达到100万次时,这些单次循环的微小耗时差异会被无限放大,最终导致两段代码的总耗时出现10倍以上的差距。
内容的提问来源于stack exchange,提问作者Kidtrixer
相关产品推荐
相关产品推荐

