我正在做一些例子来理解它是如何异步工作的。我阅读了 Trio 文档,我认为每次在循环中只能执行一个任务,并且在每个 checkpoint
中,scheduler
决定将执行哪个任务。
我做了一个例子来测试它,在 trio 例子中,我没有在我在 nursery
中生成的 child 中使用任何检查点,但这个例子比同步版本快两倍。
异步示例:
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)
结果:
4999999950000000
Total time: 8.002650737762451
为什么?我预计是同一时间,因为我没有在我的代码中使用任何检查点。好像有2个线程同时在运行或者子函数中是否有任何I/O?
最佳答案
在与 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
关于python - 没有IO操作的Trio执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51855868/