Время выполнения трио без операций ввода-вывода

Я делаю примеры, чтобы понять, как работает Python асинхронно. Я прочитал документацию по Trio и подумал, что только одна задача может быть выполнена в цикле каждый раз и в каждом checkpoint 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)

Результат:

4999999950000000
Total time: 8.002650737762451

Зачем? Я ожидал того же времени, потому что я не использую контрольные точки в своем коде. Похоже, что одновременно работают 2 потока или есть ли какие-либо операции ввода-вывода в дочерней функции?

1 ответ

Решение

После небольшого разговора с автором Трио, Nathaniel J. Smith, он нашел проблему в моем коде. Проблема в синхронном примере. Я использую глобальные переменные вместо локальных, как в асинхронном примере.

Натаниэль: "В 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
Другие вопросы по тегам