Python 3.13 с отключенным GIL работает довольно медленно.Python

Программы на Python
Anonymous
Python 3.13 с отключенным GIL работает довольно медленно.

Сообщение Anonymous »

Я провел простой тест производительности Python 3.12.0 и Python 3.13.0b3, скомпилированного с флагом --disable-gil. Программа выполняет вычисления последовательности Фибоначчи, используя ThreadPoolExecutor или ProcessPoolExecutor. В документации PEP, представляющей отключенный GIL, говорится, что существуют некоторые накладные расходы, в основном из-за смещенного подсчета ссылок с последующей блокировкой каждого объекта (https://peps.python.org/pep-0703/# Performance). Но в нем говорится, что накладные расходы на тесты производительности pyperformance составляют около 5-8%. Мой простой тест показывает значительную разницу в производительности. Действительно, Python 3.13 без GIL использует все процессоры
с ThreadPoolExecutor, но он намного медленнее, чем Python 3.12 с GIL. Основываясь на загрузке процессора и затраченном времени, мы можем сделать вывод, что с Python 3.13 мы делаем в несколько раз больше тактов по сравнению с 3.12.
Программный код:

Код: Выделить всё

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import datetime
from functools import partial
import sys
import logging
import multiprocessing

logging.basicConfig(
format='%(levelname)s: %(message)s',
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
cpus = multiprocessing.cpu_count()
pool_executor = ProcessPoolExecutor if len(sys.argv) > 1 and sys.argv[1] == '1' else ThreadPoolExecutor
python_version_str = f'{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}'
logger.info(f'Executor={pool_executor.__name__}, python={python_version_str}, cpus={cpus}')

def fibonacci(n: int) -> int:
if n < 0:
raise ValueError("Incorrect input")
elif n == 0:
return 0
elif n == 1 or n == 2:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)

start = datetime.datetime.now()

with pool_executor(8) as executor:
for task_id in range(30):
executor.submit(partial(fibonacci, 30))

executor.shutdown(wait=True)

end = datetime.datetime.now()
elapsed = end - start
logger.info(f'Elapsed: {elapsed.total_seconds():.2f} seconds')
Результаты испытаний:

Код: Выделить всё

# TEST Linux 5.15.0-58-generic, Ubuntu 20.04.6 LTS

INFO: Executor=ThreadPoolExecutor, python=3.12.0, cpus=2
INFO: Elapsed: 10.54 seconds

INFO: Executor=ProcessPoolExecutor, python=3.12.0, cpus=2
INFO: Elapsed: 4.33 seconds

INFO: Executor=ThreadPoolExecutor, python=3.13.0b3, cpus=2
INFO: Elapsed: 22.48 seconds

INFO: Executor=ProcessPoolExecutor, python=3.13.0b3, cpus=2
INFO: Elapsed: 22.03 seconds
Может ли кто-нибудь объяснить, почему я испытываю такую ​​разницу при сравнении накладных расходов с накладными расходами в тесте py Performance?
РЕДАКТИРОВАТЬ
  • Я пробовал использовать Pool_executor(cpus) вместо Pool_executor(8) -> все равно получил аналогичные результаты.
  • Я посмотрел это видео и выполнил следующий тест: https://github.com/ArjanCodes/examples/ ... 4/gil/main .py
Результаты:

Код: Выделить всё

Version of python: 3.12.0a7 (main, Oct  8 2023, 12:41:37) [GCC 9.4.0]
GIL cannot be disabled
Single-threaded: 78498 primes in 6.67 seconds
Threaded: 78498 primes in 7.89 seconds
Multiprocessed: 78498 primes in 5.85 seconds

Version of python: 3.13.0b3 experimental free-threading build (heads/3.13.0b3:7b413952e8, Jul 27 2024, 11:19:31) [GCC 9.4.0]
GIL is disabled
Single-threaded: 78498 primes in 61.42 seconds
Threaded: 78498 primes in 32.29 seconds
Multiprocessed: 78498 primes in 39.85 seconds
Итак, еще один тест на моей машине, в результате которого производительность снижается в несколько раз. Кстати. На видео мы можем видеть результаты накладных расходов, аналогичные описанным в PEP.

Подробнее здесь: https://stackoverflow.com/questions/788 ... retty-slow

Вернуться в «Python»