(一)从顺序等待到交错推进
1. 先估算等待占据的时间
三本书分别需要等待 0.06、0.02、0.04 秒。先模拟每次操作,结果仍按书目顺序收集:
# 项目文件:demos/wait_serial.py
# sleep 模拟等待响应;perf_counter 用来测一段经过时间。
from time import perf_counter, sleep
def read_title(item):
title, delay = item
sleep(delay)
return title
if __name__ == "__main__":
items = [("Python", 0.06), ("NumPy", 0.02), ("Pygame", 0.04)]
started = perf_counter()
titles = [read_title(item) for item in items]
print(titles)
print(f"经过 {perf_counter() - started:.3f} 秒")第一行得到 ['Python', 'NumPy', 'Pygame']。顺序等待的模型时间为 0.06 + 0.02 + 0.04 = 0.12 秒,实际测量还包含函数调用、调度和输出等工作。计时用来观察变化,不能把某个小数当成固定输出。
如果三个等待能够重叠,开始发出后可以在最长的等待完成时汇总,模型中接近 max(0.06, 0.02, 0.04) = 0.06 秒。这里重叠的是等待,不是把三个等待相加的结果算得更快。
2. 区分并发与并行
并发 表示多个任务在一段时间内交错推进,某个任务等待时可以推进另一个。并行 表示多个执行单元在同一时刻实际执行工作。一个事件循环也能并发等待许多响应;多个进程则可以把纯 Python 计算安排到不同 CPU 核心上。
把任务拆成“准备请求、等待网络、解析数据、保存结果”后,需要重叠的是哪一段就更清楚。数据库写入不必因为前面的请求并发就同时发生,后面的项目仍统一汇总、校验,再交给一份连接保存。