Время выполнения трио без операций ввода-вывода
Я делаю примеры, чтобы понять, как работает 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