我正在通过示例来了解它如何异步运行python。我阅读了Trio文档,并认为每次循环中只能执行一个任务,而每个checkpoint
的{{1}}都将决定执行哪个任务。
我做了一个示例进行测试,在三重示例中,我没有在scheduler
中生成的子级中使用任何检查点,但是此示例比同步版本快两倍。
异步示例:
nursery
结果:
import time
import trio
results = []
async def sum_numbers(first, last):
result = 0
for i in range(first, last):
result += i
results.append(result)
async def main():
start_time = time.time()
async with trio.open_nursery() as nursery:
nursery.start_soon(sum_numbers, 0, 50000000)
nursery.start_soon(sum_numbers, 50000000, 100000000)
print(sum(results))
print("Total time:", time.time() - start_time)
trio.run(main)
同步示例:
4999999950000000
Total time: 4.150018930435181
结果:
import time
start_time = time.time()
result = 0
for i in range(0, 100000000):
result += i
print(result)
print("Total time:", time.time() - start_time)
为什么?我期望在同一时间,因为我没有在代码中使用任何检查点。似乎有两个线程同时运行,或者子功能中是否有任何I / O?
答案 0 :(得分:9)
与Trio作者Nathaniel J. Smith进行了简短的交谈后,他在我的代码中发现了问题。问题出在同步示例中。我使用的是全局变量,而不是异步示例中的局部变量。
Nathaniel:“在CPython中,访问本地比访问全局更优化。(编译器将本地转换为数组中的偏移量,而总是在字典中按名称查找全局)”
然后,我将同步示例中的所有代码放入函数中,时间类似于异步,甚至更快。现在说得通,这是理论,现在已经证明,对我来说很清楚。谢谢!
函数同步示例:
import time
start_time = time.time()
def sum_range():
result = 0
for i in range(0, 100000000):
result += i
return result
print(sum_range())
print("Total time:", time.time() - start_time)
结果:
4999999950000000
Total time: 3.596266984939575