Всем привет. Первая статья, не кидайтесь помидорами. Буду рад услышать ваши мысли, идеи, предложения и разумную критику.
Когда-то давно я узнал что в python есть Threading. Потом я узнал про GIL. Вариантов как его обойти - масса, но я решил провести небольшое исследование и написать про то, в каких случаях стоит использовать и какие библиотеки многопоточности. Я встречал на хабре статью про GIL, там описано это всё более подробно и более глубоко. Но мне, на тот момент только начавшему разбираться в многопоточности было сложно разобраться в том что там к чему, поэтому я решил сделать своё исследование, а спустя долго время и написать о нём здесь (естественно переписав всё исследование почти с нуля)
https://github.com/mr-good-bye/asyncTime - Это мой репозиторий со всем кодом, который я использовал.
Я протестировал три библиотеки:
Threading
Asyncio
Multiprocessing
На что получил следующие интересные результаты:
Тут надо добавить что для симуляции вычислений использовалась функция
for i in range(start, n):
_ = math.sqrt(i) + math.sin(i)
Можно увидеть, что GIL работает для Threading и Asyncio, но Multiprocessing его обходит.
В тот же момент небольшие вычисления в Multiprocessing выполняются дольше, чем в остальных случаях, не углублялся из-за чего это происходит, но подозреваю, что в этом случае время создания и запуска процессов больше, чем время вычисления
Таким образом для максимального числа, которое я использовал (10e8) результат следующий:
'one' faster than 'one' by 1.0
't2' faster than 'one' by 1.0035262095048139
't6' faster than 'one' by 1.002758486863281
'mp_2' faster than 'one' by 1.835098695624356
'mp_6' faster than 'one' by 4.227536785628979
'async_6' faster than 'one' by 0.9837159203216934
— one — No async
— t2 — Threading, 2 threads
— t6 — Threading, 6 threads
— mp_2 — Multiprocessing, 2 processes
— mp_6 — Multiprocessing, 6 processes
— async_6 — Asyncio, 6 threads
Ускорение даёт только библиотека Multiprocessing, при том прирост идёт не во столько же раз, сколько процессов, а немного меньше.
Выводы
Threading и Asyncio имеет смысл и нужно использовать для неблокирующих операций, в основном для оптимизации логики приложения.
Если вам нужно ускорить вычисления - нужно смотреть в сторону Multiprocessing, либо специализированных библиотек для вычислений, или углубляться в тему GIL и многопоточности. Если последний вариант для вас, советую к прочтению статью, указанную в начале материала.
Всем спасибо за внимание, надеюсь был полезен.