You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传递数组副本与引用为何仅影响特定Python代码片段的执行效率?

为何传递列表副本/引用仅影响snippet2的执行效率?

我对比了两个代码片段的执行效率:snippet1先通过if判断再执行while循环,snippet2直接用while循环判断。测试代码如下:

import time

def snippet1(nums):
    nums.sort()
    c = 0
    for i in range(1, len(nums)):
        if nums[i] <= nums[i-1]:
            while nums[i] <= nums[i-1]:
                nums[i] += 1
                c += 1
    return c

def snippet2(nums):
    nums.sort()
    c = 0
    for i in range(1, len(nums)):
        while nums[i] <= nums[i-1]:
            nums[i] += 1
            c += 1
    return c

# Sample list of numbers
nums = [5, 1, 3, 2, 4, 2, 1, 6, 5, 8, 9, 7, 3, 2, 5]

# Measure time for snippet1
start_time = time.time()
snippet1(nums)  # 此处原代码是nums[:]改为nums
end_time = time.time()
print("Time for snippet1:", end_time - start_time)

# Measure time for snippet2
start_time = time.time()
snippet2(nums)
end_time = time.time()
print("Time for snippet2:", end_time - start_time)

原本结果符合预期,但将驱动代码中的nums[:]改为nums后,仅snippet2的执行时间出现大幅变化:

  • 使用nums[:]时:snippet1平均耗时约1.5e-05秒,snippet2平均约1.5e-05秒;
  • 使用nums时:snippet1平均耗时约2e-05秒,snippet2平均约5e-06秒。

我无法理解为何传递数组副本或引用仅会影响该代码片段?

使用nums[:]的执行结果:

Time for snippet1: 1.52587890625e-05
Time for snippet2: 1.430511474609375e-05

=== Code Execution Successful ===

使用nums的执行结果:

Time for snippet1: 2.0265579223632812e-05
Time for snippet2: 5.245208740234375e-06

=== Code Execution Successful ===

问题原因分析

  • 列表的可变性是核心:当直接传递nums(引用)时,snippet1执行后会直接修改原列表——把它排序并调整成严格递增的序列。
  • 调用snippet2时,它首先执行nums.sort(),但此时列表已经是完全有序的了!Python的list.sort()在列表已排序的情况下会触发O(n)的快速优化路径,几乎不消耗时间。同时,因为列表已经是严格递增的,snippet2里的while循环一次都不会执行,所以耗时骤降。
  • 当用nums[:]传递副本时,snippet1和snippet2各自拿到独立的原列表副本,两者都要完成完整的排序+循环调整操作,因此耗时接近。
  • 为什么snippet1的耗时没有变化?因为不管是原列表还是副本,snippet1里的if+while逻辑都会完整遍历:即使列表已经有序,if判断会跳过while,但整个循环的遍历、判断步骤一个不少,所以耗时基本稳定。

内容的提问来源于stack exchange,提问作者Hassan Mustafa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:15:06