没有IO操作的Trio执行时间

Trio execution time without IO operations

我正在做一些例子来理解它是如何异步工作的python。我阅读了 Trio 文档,我认为每次在循环中只能执行一个任务,并且在每个 checkpointscheduler 决定将执行哪个任务。

我做了一个例子来测试它,在三重奏示例中我没有使用我在 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 个线程 运行 或者 child 函数中是否有任何 I/O?

在与 Trio 作者闲聊后,Nathaniel J. Smith他在我的代码中发现了问题。问题出在同步示例中。我正在使用全局变量而不是异步示例中的局部变量。

纳撒尼尔:"In CPython, accessing locals is more optimized than accessing globals. (the compiler converts locals into offsets-in-an-array, while globals are always looked up by name in a dict)"

然后我将同步示例中的所有代码放在一个函数中,时间与异步类似,甚至更快。现在说得通了,这是理论,现在被证明了,这对我来说很清楚。谢谢!

函数中的同步示例:

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