פייתון בלי GIL

09/10/2024

גירסה 3.13 של פייתון ששוחררה ממש עכשיו היא הראשונה שתומכת רשמית בריצה ללא GIL, ואלה חדשות מספיק מלהיבות בשביל לעצור הכל ולראות את האפקט. ברמת התיאוריה ה GIL זה החלק בפייתון ששומר על ה Interpreter כשאנחנו מריצים תוכנית מרובת תהליכונים. גירסה ללא GIL אומרת שאין יותר מבני נתונים בתוך פייתון שצריך להגן עליהם, ולכן פייתון יכולה להריץ קוד מרובה תהליכים בלי נעילות - כלומר הרבה יותר מהר.

בשביל להתקין את גירסת הפייתון נטולת ה GIL עם pyenv הפעלתי:

CONFIGURE_OPTS=--disable-gil PYENV_VERSION_SUFFIX='-free-threaded' pyenv install -f -v 3.13.0rc3t

וידאתי שאני מריץ את הגירסה הנכונה עם:

$ python --version
Python 3.13.0rc3

ואז נתתי לו לספור כמה מספרים ראשוניים יש עד מיליון עם הקוד הזה:

import sys
import math
import multiprocessing.dummy as mp

def is_prime(n):
    for i in range(2, int(math.sqrt(n) + 1)):
        if n % i == 0:
            return False
    return True

if __name__ == "__main__":
    print(f"GIL enabled = {sys._is_gil_enabled()}")
    with mp.Pool(4) as p:
        print(sum(p.map(is_prime, range(1_000_000))))

אלה הזמנים שמדדתי בהרצה על הלפטופ:

ynonp@Ynons-MacBook-Air ~/tmp $ time PYTHON_GIL=0 python gil.py
GIL enabled = False
78500
PYTHON_GIL=0 python gil.py  2.83s user 0.04s system 306% cpu 0.938 total
ynonp@Ynons-MacBook-Air ~/tmp $ time PYTHON_GIL=0 python gil.py
GIL enabled = False
78500
PYTHON_GIL=0 python gil.py  2.85s user 0.04s system 305% cpu 0.944 total
ynonp@Ynons-MacBook-Air ~/tmp $ time PYTHON_GIL=0 python gil.py
GIL enabled = False
78500
PYTHON_GIL=0 python gil.py  2.88s user 0.04s system 317% cpu 0.919 total
ynonp@Ynons-MacBook-Air ~/tmp $ time PYTHON_GIL=1 python gil.py
GIL enabled = True
78500
PYTHON_GIL=1 python gil.py  2.61s user 0.05s system 96% cpu 2.753 total
ynonp@Ynons-MacBook-Air ~/tmp $ time PYTHON_GIL=1 python gil.py
GIL enabled = True
78500
PYTHON_GIL=1 python gil.py  2.62s user 0.05s system 97% cpu 2.741 total
ynonp@Ynons-MacBook-Air ~/tmp $ time PYTHON_GIL=1 python gil.py
GIL enabled = True
78500
PYTHON_GIL=1 python gil.py  2.64s user 0.05s system 93% cpu 2.865 total

בממוצע של 3 ריצות עם GIL ו-3 ללא GIL ההבדל הוא בין בערך 2.7 שניות לקצת פחות משניה, כלומר משהו כמו פי 3 יותר מהר לטובת הגירסה ללא GIL. עדיין קשה לדעת איך זה ישפיע על מודולים חיצוניים וקוד קיים ובינינו לא הייתי רץ לשדרג סקריפטים קיימים לגירסה ללא GIL, אבל זה בהחלט משהו שהייתי שוקל לפרויקטים חדשים או לסקריפטים שספציפית משתמשים בקוד מרובה תהליכונים וסובלים מבעיית איטיות.