这是我的简单代码示例:
import time
t0 = time.time()
s = 0
for i in range(1000000):
s += i
t1 = time.time()
print(s, t1 - t0)
t0 = time.time()
s = sum(i for i in range(1000000))
t1 = time.time()
print(s, t1 - t0)
Run Code Online (Sandbox Code Playgroud)
在我的电脑上(使用 Python 3.8)它打印:
499999500000 0.22901296615600586
499999500000 1.6930372714996338
Run Code Online (Sandbox Code Playgroud)
那么,执行+=100 万次比调用快 7 倍sum?这真是出乎意料。它在做什么?
编辑:我愚蠢地允许调试器附加到进程并干扰我的测量,这最终是导致缓慢的原因。随着调试器的退出,测量不再那么不可预测。正如一些答案清楚地表明的那样,我观察到的情况应该不会发生。
让我们使用timeit适当的基准测试并使比较不同的 Python 版本变得容易,让我们在 Docker 容器中运行它:
N = 1000000
def m1():
s = 0
for i in range(N):
s += i
def m2():
s = sum(i for i in range(N))
def m3():
s = sum(range(N))
Run Code Online (Sandbox Code Playgroud)
for image in python:2.7 python:3.6 python:3.7 python:3.8; do
for fun in m1 m2 m3; do
echo -n "$image" "$fun "
docker run --rm -it -v $(pwd):/app -w /app -e PYTHONDONTWRITEBYTECODE=1 "$image" python -m timeit -s 'import so62514160 as s' "s.$fun()"
done
done
Run Code Online (Sandbox Code Playgroud)
python:2.7 m1 10 loops, best of 3: 43.5 msec per loop
python:2.7 m2 10 loops, best of 3: 39.6 msec per loop
python:2.7 m3 100 loops, best of 3: 17.1 msec per loop
python:3.6 m1 10 loops, best of 3: 41.9 msec per loop
python:3.6 m2 10 loops, best of 3: 46 msec per loop
python:3.6 m3 100 loops, best of 3: 17.7 msec per loop
python:3.7 m1 5 loops, best of 5: 45 msec per loop
python:3.7 m2 5 loops, best of 5: 40.7 msec per loop
python:3.7 m3 20 loops, best of 5: 17.3 msec per loop
python:3.8 m1 5 loops, best of 5: 48.2 msec per loop
python:3.8 m2 5 loops, best of 5: 44.6 msec per loop
python:3.8 m3 10 loops, best of 5: 19.2 msec per loop
Run Code Online (Sandbox Code Playgroud)
啊,我自己找到了答案,但这又提出了另一个问题。
所以,这要快得多:
t0 = time.time()
s = sum(range(1000000))
t1 = time.time()
print(s, t1 - t0)
Run Code Online (Sandbox Code Playgroud)
结果是:
499999500000 0.05099987983703613
Run Code Online (Sandbox Code Playgroud)
因此,如预期的那样,sum比 更快+=,但生成器表达式(i for i in range(n))比其他表达式慢得多。
不得不说,这也是相当令人惊讶的。