GIL – chatgpz.de – KI-Tools & Praxiswissen https://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Tue, 11 Nov 2025 00:36:03 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Was bedeutet das Ende von GIL für Python? https://chatgpz.de/data-analytics/was-bedeutet-das-ende-von-gil-fuer-python/ https://chatgpz.de/data-analytics/was-bedeutet-das-ende-von-gil-fuer-python/#respond Tue, 11 Nov 2025 00:36:02 +0000 https://chatgpz.de/data-analytics/was-bedeutet-das-ende-von-gil-fuer-python/ [ad_1]

Was bedeutet das Ende von GIL für Python?Was bedeutet das Ende von GIL für Python?
Bild vom Herausgeber

# Einführung

Seit Jahrzehnten ist Pythons World Interpreter Lock (GIL) Segen und Fluch zugleich. Aus diesem Grund ist Python einfach, vorhersehbar und zugänglich. sondern auch der Grund, warum es Probleme mit echtem Multithreading gibt.

Entwickler haben es verflucht, es optimiert und sogar ganze Architekturen gebaut, um es zu umgehen. Mit den bevorstehenden Änderungen in Python 3.13 und höher wird die GIL nun endgültig abgebaut. Die Auswirkungen sind nicht nur technischer Natur; Sie sind kulturell. Dieser Wandel könnte die Artwork und Weise, wie wir Python in der Neuzeit schreiben, skalieren und sogar denken, neu definieren.

# Der lange Schatten der GIL

Um zu verstehen, warum die Entfernung der GIL wichtig ist, muss man begreifen, was sie wirklich bewirkt hat. Die GIL struggle ein Mutex – eine globale Sperre, die sicherstellt, dass jeweils nur ein Thread Python-Bytecode ausführt. Dies machte die Speicherverwaltung einfach und sicher, insbesondere in den frühen Tagen, als der Interpreter von Python noch nicht für Parallelität ausgelegt struggle. Es schützte Entwickler vor Race Situations, allerdings mit enormen Kosten: Python konnte niemals echte Parallelität zwischen Threads auf Multi-Core-CPUs erreichen.

Das Ergebnis struggle ein unsicherer Waffenstillstand. Bibliotheken mögen NumPy, TensorFlowUnd PyTorch hat die GIL umgangen, indem sie sie während umfangreicher C-Degree-Berechnungen freigegeben hat. Andere verließen sich auf Multiprocessing und führten separate Interpreterprozesse ein, um Parallelität zu simulieren. Es hat funktioniert – allerdings auf Kosten der Komplexität und des Speicheraufwands. Die GIL wurde zu einem festen Sternchen in Pythons Lebenslauf: „Schnell genug … für einen einzelnen Kern.“

Jahrelang wirkten die Diskussionen über die Abschaffung der GIL quick mythisch. Vorschläge kamen und gingen und scheiterten meist unter der Final der Abwärtskompatibilität und Leistungsrückgängen. Doch dank der Bemühungen hinter PEP 703 ist das Ende der Sperre nun endlich realistisch – und es verändert alles.

# PEP 703: Das Schloss löst sich

PEP 703 mit dem Titel „Making the World Interpreter Lock Optionally available“ markierte einen historischen Wandel in der Designphilosophie von Python. Anstatt die GIL vollständig zu entfernen, wird ein Construct von Python eingeführt, der ohne sie läuft. Dies bedeutet, dass Entwickler Python je nach Anwendungsfall mit oder ohne GIL kompilieren können. Es ist vorsichtig, aber es ist ein Fortschritt.

Die wichtigste Neuerung besteht nicht nur darin, das Schloss zu entfernen; Es geht darum, das Speichermodell von CPython umzugestalten. Speicherobjekte und Referenzzählung – das Rückgrat der Rubbish Assortment von Python – mussten neu gestaltet werden, um sicher über Threads hinweg zu funktionieren. Die Implementierung führt feinkörnige Sperren und atomare Referenzzähler ein und gewährleistet so die Datenkonsistenz ohne globale Serialisierung.

Benchmarks zeigen erste Aussichten. CPU-gebundene Aufgaben die zuvor durch die GIL einen Engpass hatten, skalieren jetzt quick linear über die Kerne hinweg. Der Kompromiss beeinträchtigt die Single-Threaded-Leistung leicht, aber für viele Workloads – insbesondere Knowledge Science, KI und Backend-Server – ist das ein geringer Preis. Die Überschrift lautet nicht nur „Python wird schneller“. Es heißt: „Python geht endlich parallel.“

# Der Welleneffekt im gesamten Ökosystem

Wenn man eine Grundannahme wie die GIL entfernt, gerät alles, was darauf aufbaut, ins Wanken. Bibliotheken, Frameworks und bestehende Cloud-Automatisierungsworkflows müssen angepasst werden. Vor allem C-Erweiterungen stehen vor einer Rechenschaft. Viele wurden unter der Annahme geschrieben, dass die GIL den gemeinsamen Speicher schützen würde. Ohne sie könnten über Nacht Parallelitätsfehler auftauchen.

Um den Übergang zu erleichtern, führt die Python-Neighborhood Kompatibilitätsebenen und APIs ein, die Thread-Sicherheitsdetails abstrahieren. Der größere Wandel ist jedoch philosophischer Natur: Entwickler können jetzt Systeme entwerfen, die echte Parallelität voraussetzen. Stellen Sie sich Datenpipelines vor, in denen Parsing, Berechnung und Serialisierung tatsächlich parallel laufen – oder Net-Frameworks, die Anfragen mit echtem Multithread-Durchsatz verarbeiten, ohne dass eine Prozessverzweigung erforderlich ist.

Für Datenwissenschaftler bedeutet dies ein schnelleres Modelltraining und reaktionsfähigere Instruments. Pandas, NumPyUnd SciPy könnte bald echte parallele Schleifen nutzen, ohne auf Multiprocessing zurückgreifen zu müssen.

// Was es für Python-Entwickler bedeutet

Für Entwickler ist diese Änderung sowohl aufregend als auch einschüchternd. Das Ende der GIL bedeutet, dass sich Python eher wie andere Multithread-Sprachen wie Java, C++ oder Go verhält. Das bedeutet mehr Macht, aber auch mehr Verantwortung. Race Situations, Deadlocks und Synchronisationsfehler sind keine abstrakten Sorgen mehr. Erinnern als Deep-Studying-Modelle anspruchsvoller und zugleich komplexer waren?

Die Einfachheit, die die GIL bot, ging zu Lasten der Skalierbarkeit, schützte Entwickler aber auch vor einer Klasse von Fehlern, mit denen sich viele Python-Programmierer nie befasst hatten. Mit der Weiterentwicklung der Nebenläufigkeitsgeschichte von Python muss sich auch seine Pädagogik weiterentwickeln. Tutorials, Dokumentationen und Frameworks müssen neue Muster für sichere Parallelität vermitteln. Instruments wie Thread-sichere Container, nebenläufige Datenstrukturen und atomare Operationen werden für die alltägliche Codierung von zentraler Bedeutung sein.

Dies ist die Artwork von Komplexität, die mit der Reife einhergeht. Die GIL hielt Python komfortabel, aber eingeschränkt. Seine Entfernung zwingt die Neighborhood, sich einer Wahrheit zu stellen: Wenn Python in Hochleistungs- und KI-gesteuerten Kontexten related bleiben will, muss es erwachsen werden.

# Wie dies die Identität von Python verändern könnte

Der Reiz von Python lag schon immer in seiner Klarheit und Lesbarkeit – Dies erstreckt sich auch darauf, wie einfach es ist, Anwendungen mit großen Sprachmodellen zu erstellen. Seltsamerweise hat die GIL dazu beigetragen. Dadurch konnten Entwickler Multithread-ähnlichen Code schreiben, ohne den mentalen Aufwand für die Verwaltung echter Parallelität auf sich nehmen zu müssen. Das Entfernen könnte Python zu einer neuen Identität verhelfen: einer, bei der Leistung und Skalierbarkeit mit C++ oder Rust konkurrieren, aber die Einfachheit, die es definiert hat, unter Druck steht.

Diese Entwicklung spiegelt einen umfassenderen Wandel im Python-Ökosystem wider. Die Sprache ist nicht mehr nur ein Skript-Instrument, sondern eine echte Plattform für Datenwissenschaft, KI und Backend-Engineering. Diese Bereiche erfordern Durchsatz und Parallelität, nicht nur Eleganz. Die Entfernung der GIL verrät nicht die Wurzeln von Python; Es erkennt seine neue Rolle in einer datenintensiven Welt mit mehreren Kernen an.

# Die Zukunft: Ein schnelleres, freies Python

Wenn die GIL endgültig in die Geschichte eingeht, wird sie nicht nur als technischer Meilenstein in Erinnerung bleiben. Es wird als Wendepunkt in Pythons Erzählung gesehen, als ein Second, in dem der Pragmatismus das Erbe überholte. Dieselbe Sprache, die einst mit Parallelität zu kämpfen hatte, wird endlich die volle Leistungsfähigkeit moderner {Hardware} nutzen können.

Für Entwickler bedeutet es, alte Annahmen neu zu schreiben. Für Bibliotheksautoren bedeutet dies eine Umgestaltung zur Thread-Sicherheit. Und für die Neighborhood ist es eine Erinnerung daran, dass Python nicht statisch ist – es ist lebendig, entwickelt sich weiter und hat keine Angst davor, sich seinen Grenzen zu stellen.

In gewisser Weise ist das Ende der GIL poetisch. Die Sperre, die Python schützte, hielt es auch klein. Durch die Entfernung wird nicht nur Leistung, sondern auch Potenzial freigesetzt. Die Sprache, die dadurch wuchs, dass sie „Nein“ zur Komplexität sagte, ist jetzt ausgereift genug, um „Ja“ zur Parallelität zu sagen – und zur Zukunft, die damit einhergeht.

Nahla Davies ist Softwareentwickler und technischer Autor. Bevor sie sich hauptberuflich dem technischen Schreiben widmete, schaffte sie es – neben anderen faszinierenden Dingen –, als leitende Programmiererin bei einer Inc. 5.000-Organisation für experimentelles Branding zu arbeiten, zu deren Kunden Samsung, Time Warner, Netflix und Sony gehören.

[ad_2]

]]>
https://chatgpz.de/data-analytics/was-bedeutet-das-ende-von-gil-fuer-python/feed/ 0 13875
Python 3.14 und das Ende der GIL https://chatgpz.de/machine-learning/python-3-14-und-das-ende-der-gil/ https://chatgpz.de/machine-learning/python-3-14-und-das-ende-der-gil/#respond Sat, 18 Oct 2025 21:39:17 +0000 https://chatgpz.de/machine-learning/python-3-14-und-das-ende-der-gil/ [ad_1]

einer der am meisten erwarteten Veröffentlichungen der letzten Zeit, ist endlich da. Der Grund dafür ist, dass in dieser Model mehrere spannende Verbesserungen implementiert wurden, darunter:

Unterdolmetscher. Diese sind seit 20 Jahren in Python verfügbar, aber um sie nutzen zu können, musste man auf die Codierung in C umsteigen. Jetzt können sie direkt aus Python selbst verwendet werden.

T-Strings. Vorlagenzeichenfolgen sind eine neue Methode zur benutzerdefinierten Zeichenfolgenverarbeitung. Sie verwenden die bekannte Syntax von F-Strings, geben aber im Gegensatz zu F-Strings ein Objekt zurück, das sowohl den statischen als auch den interpolierten Teil des Strings darstellt, und nicht einen einfachen String.

Ein Simply-in-Time-Compiler. Dies ist noch eine experimentelle Funktion und sollte nicht in Produktionssystemen verwendet werden. Es verspricht jedoch eine Leistungssteigerung für bestimmte Anwendungsfälle.

Es gibt viele weitere Verbesserungen in Python 3.14, aber in diesem Artikel geht es nicht um diese oder die oben erwähnten.

Stattdessen werden wir die wahrscheinlich am meisten erwartete Funktion dieser Model besprechen: Free-Threaded-Python, auch bekannt als GIL-freies Python. Beachten Sie, dass normales Python 3.14 weiterhin mit aktivierter GIL läuft, Sie können jedoch eine separate Free-Thread-Model herunterladen (oder erstellen). Ich zeige Ihnen, wie Sie es herunterladen und installieren, und demonstriere anhand mehrerer Codierungsbeispiele einen Vergleich der Laufzeiten zwischen regulärem und GIL-freiem Python 3.14.

Was ist die GIL?

Viele von Ihnen werden den World Interpreter Lock (GIL) in Python kennen. Die GIL ist ein Mutex – ein Sperrmechanismus – der zum Synchronisieren des Zugriffs auf Ressourcen verwendet wird und in Python sicherstellt, dass jeweils nur ein Thread Bytecode ausführt.

Dies hat einerseits mehrere Vorteile, darunter die einfachere Thread- und Speicherverwaltung, die Vermeidung von Race Circumstances und die Integration von Python in C/C++-Bibliotheken.

Andererseits kann die GIL die Parallelität unterdrücken. Mit der GIL ist keine echte Parallelität für CPU-gebundene Aufgaben über mehrere CPU-Kerne innerhalb eines einzelnen Python-Prozesses möglich.

Warum das wichtig ist

Mit einem Wort, „Leistung“.

Da bei der Free-Thread-Ausführung alle verfügbaren Kerne Ihres Methods gleichzeitig genutzt werden können, wird Code oft schneller ausgeführt. Als Datenwissenschaftler und ML oder Dateningenieure gilt dies nicht nur für Ihren Code, sondern auch für den Code, der die Systeme, Frameworks und Bibliotheken erstellt, auf die Sie sich verlassen.

Viele Aufgaben des maschinellen Lernens und der Datenwissenschaft sind rechenintensiv, insbesondere während des Modelltrainings und der Datenvorverarbeitung. Die Entfernung der GIL könnte zu erheblichen Leistungsverbesserungen für diese CPU-gebundenen Aufgaben führen.

Viele beliebte Bibliotheken in Python sind mit Einschränkungen konfrontiert, weil sie die GIL umgehen mussten. Seine Entfernung könnte zu Folgendem führen:

  • Vereinfachte und möglicherweise effizientere Implementierungen dieser Bibliotheken
  • Neue Optimierungsmöglichkeiten in bestehenden Bibliotheken
  • Entwicklung neuer Bibliotheken, die die Vorteile der Parallelverarbeitung voll ausnutzen können

Set up der Free-Threaded-Python-Model

Wenn Sie ein Linux-Benutzer sind, besteht die einzige Möglichkeit, Python mit kostenlosem Threading zu erhalten, darin, es selbst zu erstellen. Wenn Sie wie ich Home windows (oder macOS) verwenden, können Sie es mit den offiziellen Installationsprogrammen von der Python-Web site installieren. Während des Vorgangs haben Sie die Möglichkeit, Ihre Set up anzupassen. Suchen Sie nach einem Kontrollkästchen, um die Free-Thread-Binärdateien einzuschließen. Dadurch wird ein separater Interpreter installiert, mit dem Sie Ihren Code ohne die GIL ausführen können. Ich zeige, wie die Set up auf einem 64-Bit-Home windows-System funktioniert.

Klicken Sie zunächst auf die folgende URL:

https://www.python.org/downloads/launch/python-3140

Scrollen Sie nach unten, bis Sie eine Tabelle sehen, die so aussieht.

Bild von der Python-Web site

Klicken Sie nun auf den Hyperlink Home windows Installer (64-Bit). Sobald die ausführbare Datei heruntergeladen wurde, öffnen Sie sie und klicken Sie im ersten angezeigten Installationsbildschirm auf Passen Sie die Set up an Hyperlink. Beachten Sie, dass ich das auch überprüft habe Fügen Sie Python.exe zum Pfad hinzu Kontrollkästchen.

Wählen Sie im nächsten Bildschirm die optionalen Extras aus, die Sie zur Set up hinzufügen möchten, und klicken Sie dann auf Nächste wieder. An diesem Punkt sollten Sie einen Bildschirm wie diesen sehen:

Bild vom Python-Installationsprogramm

Stellen Sie sicher, dass das Kontrollkästchen daneben aktiviert ist Laden Sie kostenlose Binärdateien herunter ausgewählt ist. Ich habe das auch überprüft Installieren Sie Python 3.14 für alle Benutzer Choice.

Klicken Sie auf die Schaltfläche „Installieren“.

Suchen Sie nach Abschluss des Downloads im Installationsordner nach einer Python-Anwendungsdatei mit einem „t“ am Ende des Namens. Dies ist die GIL-freie Model von Python. Die Anwendungsdatei namens Python ist die reguläre ausführbare Python-Datei. In meinem Fall hieß das GIL-freie Python Python3.14t. Sie können überprüfen, ob es korrekt installiert wurde, indem Sie dies in eine Befehlszeile eingeben.

C:Usersthoma>python3.14t

Python 3.14.0 free-threading construct (tags/v3.14.0:ebf955d, Oct  7 2025, 10:13:09) (MSC v.1944 64 bit (AMD64)) on win32
Sort "assist", "copyright", "credit" or "license" for extra data.
>>> 

Wenn Sie das sehen, sind Sie startklar. Überprüfen Sie andernfalls, ob der Installationsort zu Ihrer PATH-Umgebungsvariablen hinzugefügt wurde und/oder überprüfen Sie Ihre Installationsschritte noch einmal.

Da wir die GIL-freien Python-Laufzeiten mit den regulären Python-Laufzeiten vergleichen, sollten wir auch überprüfen, ob diese auch korrekt installiert sind.

C:Usersthoma>python
Python 3.14.0 (tags/v3.14.0:ebf955d, Oct  7 2025, 10:15:03) (MSC v.1944 64 bit (AMD64)) on win32
Sort "assist", "copyright", "credit" or "license" for extra data.
>>>

GIL vs. GIL-freies Python

Beispiel 1 – Primzahlen finden

Geben Sie Folgendes in eine Python-Codedatei ein, z. B. example1.py

#
# example1.py
#

import threading
import time
import multiprocessing

def is_prime(n):
    """Verify if a quantity is prime."""
    if n < 2:
        return False
    for i in vary(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

def find_primes(begin, finish):
    """Discover all prime numbers within the given vary."""
    primes = ()
    for num in vary(begin, finish + 1):
        if is_prime(num):
            primes.append(num)
    return primes

def employee(worker_id, begin, finish):
    """Employee perform to search out primes in a selected vary."""
    print(f"Employee {worker_id} beginning")
    primes = find_primes(begin, finish)
    print(f"Employee {worker_id} discovered {len(primes)} primes")

def foremost():
    """Most important perform to coordinate the multi-threaded prime search."""
    start_time = time.time()

    # Get the variety of CPU cores
    num_cores = multiprocessing.cpu_count()
    print(f"Variety of CPU cores: {num_cores}")

    # Outline the vary for prime search
    total_range = 2_000_000
    chunk_size = total_range // num_cores

    threads = ()
    # Create and begin threads equal to the variety of cores
    for i in vary(num_cores):
        begin = i * chunk_size + 1
        finish = (i + 1) * chunk_size if i < num_cores - 1 else total_range
        thread = threading.Thread(goal=employee, args=(i, begin, finish))
        threads.append(thread)
        thread.begin()

    # Anticipate all threads to finish
    for thread in threads:
        thread.be part of()

    # Calculate and print the overall execution time
    end_time = time.time()
    total_time = end_time - start_time
    print(f"All staff accomplished in {total_time:.2f} seconds")

if __name__ == "__main__":
    foremost()

Der is_prime Funktion prüft, ob eine gegebene Zahl eine Primzahl ist.

Der find_primes Die Funktion findet alle Primzahlen innerhalb eines bestimmten Bereichs.

Der Arbeitnehmer Die Funktion ist das Ziel für jeden Thread und findet Primzahlen in einem bestimmten Bereich.

Der hauptsächlich Funktion koordiniert die Multithread-Primärsuche:

  • Es unterteilt den Gesamtbereich in die Anzahl der Blöcke, die der Anzahl der Kerne des Methods entspricht (in meinem Fall 32).
  • Erstellt und startet 32 ​​Threads, wobei jeder einen kleinen Teil des Bereichs durchsucht.
  • Wartet, bis alle Threads abgeschlossen sind.
  • Berechnet die Gesamtausführungszeit und druckt sie aus.

Timing-Ergebnisse

Mal sehen, wie lange die Ausführung mit normalem Python dauert.

C:Usersthomaprojectspython-gil>python example1.py
Variety of CPU cores: 32
Employee 0 beginning
Employee 1 beginning
Employee 0 discovered 6275 primes
Employee 2 beginning
Employee 3 beginning
Employee 1 discovered 5459 primes
Employee 4 beginning
Employee 2 discovered 5230 primes
Employee 3 discovered 5080 primes
...
...
Employee 27 discovered 4346 primes
Employee 15 beginning
Employee 22 discovered 4439 primes
Employee 30 discovered 4338 primes
Employee 28 discovered 4338 primes
Employee 31 discovered 4304 primes
Employee 11 discovered 4612 primes
Employee 15 discovered 4492 primes
Employee 25 discovered 4346 primes
Employee 26 discovered 4377 primes
All staff accomplished in 3.70 seconds

Jetzt mit der GIL-freien Model:

C:Usersthomaprojectspython-gil>python3.14t example1.py
Variety of CPU cores: 32
Employee 0 beginning
Employee 1 beginning
Employee 2 beginning
Employee 3 beginning
...
...
Employee 19 discovered 4430 primes
Employee 29 discovered 4345 primes
Employee 30 discovered 4338 primes
Employee 18 discovered 4520 primes
Employee 26 discovered 4377 primes
Employee 27 discovered 4346 primes
Employee 22 discovered 4439 primes
Employee 23 discovered 4403 primes
Employee 31 discovered 4304 primes
Employee 28 discovered 4338 primes
All staff accomplished in 0.35 seconds

Das ist ein beeindruckender Anfang. Eine 10-fache Verbesserung der Laufzeit.

Beispiel 2 – Mehrere Dateien gleichzeitig lesen.

In diesem Beispiel verwenden wir das Modell concurrent.futures, um mehrere Textdateien gleichzeitig zu lesen und die Anzahl der Zeilen und Wörter in jeder Datei zu zählen und anzuzeigen.

Bevor wir das tun, müssen wir einige Datendateien verarbeiten. Sie können dazu den folgenden Python-Code verwenden. Es generiert jeweils 1.000.000 zufällige, unsinnige Sätze und schreibt sie in 20 separate Textdateien, Sätze_01.txt, Sätze_02.txt usw.

import os
import random
import time

# --- Configuration ---
NUM_FILES = 20
SENTENCES_PER_FILE = 1_000_000
WORDS_PER_SENTENCE_MIN = 8
WORDS_PER_SENTENCE_MAX = 20
OUTPUT_DIR = "fake_sentences" # Listing to save lots of the information

# --- 1. Generate a pool of phrases ---
# Utilizing a small checklist of frequent phrases for selection.
# In an actual state of affairs, you may load a a lot bigger dictionary.
word_pool = (
    "the", "be", "to", "of", "and", "a", "in", "that", "have", "i",
    "it", "for", "not", "on", "with", "he", "as", "you", "do", "at",
    "this", "however", "his", "by", "from", "they", "we", "say", "her", "she",
    "or", "an", "will", "my", "one", "all", "would", "there", "their", "what",
    "so", "up", "out", "if", "about", "who", "get", "which", "go", "me",
    "when", "make", "can", "like", "time", "no", "simply", "him", "know", "take",
    "individuals", "into", "yr", "your", "good", "some", "might", "them", "see", "different",
    "than", "then", "now", "look", "solely", "come", "its", "over", "suppose", "additionally",
    "again", "after", "use", "two", "how", "our", "work", "first", "nicely", "manner",
    "even", "new", "need", "as a result of", "any", "these", "give", "day", "most", "us",
    "apple", "banana", "automotive", "home", "pc", "cellphone", "espresso", "water", "sky", "tree",
    "comfortable", "unhappy", "huge", "small", "quick", "sluggish", "pink", "blue", "inexperienced", "yellow"
)

# Guarantee output listing exists
os.makedirs(OUTPUT_DIR, exist_ok=True)

print(f"Beginning to generate {NUM_FILES} information, every with {SENTENCES_PER_FILE:,} sentences.")
print(f"Complete sentences to generate: {NUM_FILES * SENTENCES_PER_FILE:,}")
start_time = time.time()

for file_idx in vary(NUM_FILES):
    file_name = os.path.be part of(OUTPUT_DIR, f"sentences_{file_idx + 1:02d}.txt")
    
    print(f"nGenerating and writing to {file_name}...")
    file_start_time = time.time()
    
    with open(file_name, 'w', encoding='utf-8') as f:
        for sentence_idx in vary(SENTENCES_PER_FILE):
            # 2. Assemble faux sentences
            num_words = random.randint(WORDS_PER_SENTENCE_MIN, WORDS_PER_SENTENCE_MAX)
            
            # Randomly choose phrases
            sentence_words = random.selections(word_pool, ok=num_words)
            
            # Be a part of phrases, capitalize first, add a interval
            sentence = " ".be part of(sentence_words).capitalize() + ".n"
            
            # 3. Write to file
            f.write(sentence)
            
            # Optionally available: Print progress for big information
            if (sentence_idx + 1) % 100_000 == 0:
                print(f"  {sentence_idx + 1:,} sentences written to {file_name}...")
                
    file_end_time = time.time()
    print(f"Completed {file_name} in {file_end_time - file_start_time:.2f} seconds.")

total_end_time = time.time()
print(f"nAll information generated! Complete time: {total_end_time - start_time:.2f} seconds.")
print(f"Recordsdata saved within the '{OUTPUT_DIR}' listing.")

So sieht der Anfang von Sätzen_01.txt aus:

New then espresso have who banana his their how yr additionally there i take.
Cellphone go or with over who one at cellphone there on will.
With or how my us him our unhappy as do be take nicely manner with inexperienced small these.
Not from the 2 that so good sluggish new.
See look water me do new work new into on which be tree how an would out unhappy.
By be into then work into we they sky sluggish that each one who additionally.
Come use would have again from as after in again he give there pink additionally first see.
Solely come so nicely huge into some my into time its banana for come or what work.
How solely espresso out approach to simply tree when by there for pc work individuals sky by this into.
Than say out on it how she apple pc us nicely then sky sky day by different after not.
You content know a sluggish for for comfortable then additionally with apple suppose look go when.
As who for than two we up any can banana at.
Espresso a up of up these inexperienced small this us give we.
These we do as a result of how know me pc banana again cellphone manner time in what.

OK, jetzt können wir messen, wie lange es dauert, diese Dateien zu lesen. Hier ist der Code, den wir testen werden. Es liest einfach jede Datei, zählt die Zeilen und Wörter und gibt die Ergebnisse aus.

import concurrent.futures
import os
import time

def process_file(filename):
    """
    Course of a single file, returning its line depend and phrase depend.
    """
    strive:
        with open(filename, 'r') as file:
            content material = file.learn()
            strains = content material.break up('n')
            phrases = content material.break up()
            return filename, len(strains), len(phrases)
    besides Exception as e:
        return filename, -1, -1  # Return -1 for each counts if there's an error

def foremost():
    start_time = time.time()  # Begin the timer

    # Checklist to carry our information
    information = (f"./knowledge/sentences_{i:02d}.txt" for i in vary(1, 21))  # Assumes 20 information named file_1.txt to file_20.txt

    # Use a ThreadPoolExecutor to course of information in parallel
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        # Submit all file processing duties
        future_to_file = {executor.submit(process_file, file): file for file in information}

        # Course of outcomes as they full
        for future in concurrent.futures.as_completed(future_to_file):
            file = future_to_file(future)
            strive:
                filename, line_count, word_count = future.consequence()
                if line_count == -1:
                    print(f"Error processing {filename}")
                else:
                    print(f"{filename}: {line_count} strains, {word_count} phrases")
            besides Exception as exc:
                print(f'{file} generated an exception: {exc}')

    end_time = time.time()  # Finish the timer
    print(f"Complete execution time: {end_time - start_time:.2f} seconds")

if __name__ == "__main__":
    foremost()

Timing-Ergebnisse

Zuerst normales Python.

C:Usersthomaprojectspython-gil>python example2.py

./knowledge/sentences_09.txt: 1000001 strains, 14003319 phrases
./knowledge/sentences_01.txt: 1000001 strains, 13999989 phrases
./knowledge/sentences_05.txt: 1000001 strains, 13998447 phrases
./knowledge/sentences_07.txt: 1000001 strains, 14004961 phrases
./knowledge/sentences_02.txt: 1000001 strains, 14009745 phrases
./knowledge/sentences_10.txt: 1000001 strains, 14000166 phrases
./knowledge/sentences_06.txt: 1000001 strains, 13995223 phrases
./knowledge/sentences_04.txt: 1000001 strains, 14005683 phrases
./knowledge/sentences_03.txt: 1000001 strains, 14004290 phrases
./knowledge/sentences_12.txt: 1000001 strains, 13997193 phrases
./knowledge/sentences_08.txt: 1000001 strains, 13995506 phrases
./knowledge/sentences_15.txt: 1000001 strains, 13998555 phrases
./knowledge/sentences_11.txt: 1000001 strains, 14001299 phrases
./knowledge/sentences_14.txt: 1000001 strains, 13998347 phrases
./knowledge/sentences_13.txt: 1000001 strains, 13998035 phrases
./knowledge/sentences_19.txt: 1000001 strains, 13999642 phrases
./knowledge/sentences_20.txt: 1000001 strains, 14001696 phrases
./knowledge/sentences_17.txt: 1000001 strains, 14000184 phrases
./knowledge/sentences_18.txt: 1000001 strains, 13999968 phrases
./knowledge/sentences_16.txt: 1000001 strains, 14000771 phrases
Complete execution time: 18.77 seconds

Nun zur GIL-freien Model

C:Usersthomaprojectspython-gil>python3.14t example2.py

./knowledge/sentences_02.txt: 1000001 strains, 14009745 phrases
./knowledge/sentences_03.txt: 1000001 strains, 14004290 phrases
./knowledge/sentences_08.txt: 1000001 strains, 13995506 phrases
./knowledge/sentences_07.txt: 1000001 strains, 14004961 phrases
./knowledge/sentences_04.txt: 1000001 strains, 14005683 phrases
./knowledge/sentences_05.txt: 1000001 strains, 13998447 phrases
./knowledge/sentences_01.txt: 1000001 strains, 13999989 phrases
./knowledge/sentences_10.txt: 1000001 strains, 14000166 phrases
./knowledge/sentences_06.txt: 1000001 strains, 13995223 phrases
./knowledge/sentences_09.txt: 1000001 strains, 14003319 phrases
./knowledge/sentences_12.txt: 1000001 strains, 13997193 phrases
./knowledge/sentences_11.txt: 1000001 strains, 14001299 phrases
./knowledge/sentences_18.txt: 1000001 strains, 13999968 phrases
./knowledge/sentences_14.txt: 1000001 strains, 13998347 phrases
./knowledge/sentences_13.txt: 1000001 strains, 13998035 phrases
./knowledge/sentences_16.txt: 1000001 strains, 14000771 phrases
./knowledge/sentences_19.txt: 1000001 strains, 13999642 phrases
./knowledge/sentences_15.txt: 1000001 strains, 13998555 phrases
./knowledge/sentences_17.txt: 1000001 strains, 14000184 phrases
./knowledge/sentences_20.txt: 1000001 strains, 14001696 phrases
Complete execution time: 5.13 seconds

Nicht ganz so beeindruckend wie unser erstes Beispiel, aber immer noch sehr intestine und zeigt eine mehr als dreifache Verbesserung.

Beispiel 3 – Matrixmultiplikation

Wir werden das verwenden Einfädeln Modul dafür. Hier ist der Code, den wir ausführen werden.

import threading
import time
import os

def multiply_matrices(A, B, consequence, start_row, end_row):
    """Multiply a submatrix of A and B and retailer the consequence within the corresponding submatrix of consequence."""
    for i in vary(start_row, end_row):
        for j in vary(len(B(0))):
            sum_val = 0
            for ok in vary(len(B)):
                sum_val += A(i)(ok) * B(ok)(j)
            consequence(i)(j) = sum_val

def foremost():
    """Most important perform to coordinate the multi-threaded matrix multiplication."""
    start_time = time.time()

    # Outline the scale of the matrices
    measurement = 1000
    A = ((1 for _ in vary(measurement)) for _ in vary(measurement))
    B = ((1 for _ in vary(measurement)) for _ in vary(measurement))
    consequence = ((0 for _ in vary(measurement)) for _ in vary(measurement))

    # Get the variety of CPU cores to determine on the variety of threads
    num_threads = os.cpu_count()
    print(f"Variety of CPU cores: {num_threads}")

    chunk_size = measurement // num_threads

    threads = ()
    # Create and begin threads
    for i in vary(num_threads):
        start_row = i * chunk_size
        end_row = measurement if i == num_threads - 1 else (i + 1) * chunk_size
        thread = threading.Thread(goal=multiply_matrices, args=(A, B, consequence, start_row, end_row))
        threads.append(thread)
        thread.begin()

    # Anticipate all threads to finish
    for thread in threads:
        thread.be part of()

    end_time = time.time()

    # Simply print a small nook to confirm
    print("High-left 5x5 nook of the consequence matrix:")
    for r_idx in vary(5):
        print(consequence(r_idx)(:5))

    print(f"Complete execution time (matrix multiplication): {end_time - start_time:.2f} seconds")

if __name__ == "__main__":
    foremost()

Der Code führt eine Matrixmultiplikation von zwei 1000×1000-Matrizen parallel unter Verwendung mehrerer CPU-Kerne durch. Es unterteilt die Ergebnismatrix in Blöcke, weist jeden Block einem separaten Prozess zu (entspricht der Anzahl der CPU-Kerne) und jeder Prozess berechnet seinen zugewiesenen Teil der Matrixmultiplikation unabhängig. Schließlich wartet es darauf, dass alle Prozesse abgeschlossen sind, und meldet die Gesamtausführungszeit. So wird demonstriert, wie Multiprocessing genutzt werden kann, um CPU-gebundene Aufgaben zu beschleunigen.

Timing-Ergebnisse

Reguläres Python:

C:Usersthomaprojectspython-gil>python example3.py
Variety of CPU cores: 32
High-left 5x5 nook of the consequence matrix:
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
Complete execution time (matrix multiplication): 43.95 seconds

GIL-freies Python:

C:Usersthomaprojectspython-gil>python3.14t example3.py
Variety of CPU cores: 32
High-left 5x5 nook of the consequence matrix:
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
Complete execution time (matrix multiplication): 4.56 seconds

Mit GIL-freiem Python erzielen wir erneut eine quick zehnfache Verbesserung. Nicht zu schäbig.

GIL-frei ist nicht immer besser.

Ein interessanter Punkt ist, dass ich es bei diesem letzten Take a look at auch mit einer Multiprozessorversion des Codes versucht habe. Es stellte sich heraus, dass das reguläre Python deutlich schneller (28 %) battle als das GIL-freie Python. Ich werde nicht den Code präsentieren, sondern nur die Ergebnisse.

Zeitangaben

Zuerst normales Python (Multiprocessing).

C:Usersthomaprojectspython-gil>python example4.py
Variety of CPU cores: 32
High-left 5x5 nook of the consequence matrix:
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
Complete execution time (matrix multiplication): 4.49 seconds

GIL-freie Model (Multiprocessing)

C:Usersthomaprojectspython-gil>python3.14t example4.py
Variety of CPU cores: 32
High-left 5x5 nook of the consequence matrix:
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
(1000, 1000, 1000, 1000, 1000)
Complete execution time (matrix multiplication): 6.29 seconds

Wie immer in solchen Situationen ist es wichtig, gründlich zu testen.

Denken Sie daran, dass diese letzten Beispiele sind gerecht Exams, um den Unterschied zwischen GIL und GIL-freiem Python aufzuzeigen. Die Verwendung einer externen Bibliothek wie NumPy zur Durchführung der Matrixmultiplikation wäre mindestens eine Größenordnung schneller als beides.

Ein weiterer Punkt, den Sie beachten sollten, wenn Sie sich für die Verwendung von Free-Threading-Python in Ihren Workloads entscheiden, ist, dass nicht alle Bibliotheken von Drittanbietern, die Sie möglicherweise verwenden möchten, damit kompatibel sind. Die Liste der inkompatiblen Bibliotheken ist klein und wird mit jeder Veröffentlichung kleiner, aber Sie sollten dies im Hinterkopf behalten. Um eine Liste davon anzuzeigen, klicken Sie bitte auf den untenstehenden Hyperlink.

https://ft-checker.com

Zusammenfassung

In diesem Artikel besprechen wir eine möglicherweise bahnbrechende Funktion der neuesten Model von Python 3.14: die Einführung einer optionalen „Free-Threaded“-Model, die die World Interpreter Lock (GIL) entfernt. Die GIL ist ein Mechanismus in Normal-Python, der die Speicherverwaltung vereinfacht, indem er sicherstellt, dass jeweils nur ein Thread Python-Bytecode ausführt. Dies kann zwar in manchen Fällen nützlich sein, verhindert jedoch eine echte Parallelverarbeitung auf Multi-Core-CPUs für CPU-intensive Aufgaben.

Die Entfernung der GIL im Free-Threaded-Construct dient in erster Linie der Verbesserung Leistung. Dies kann besonders für Datenwissenschaftler und Ingenieure für maschinelles Lernen nützlich sein, deren Arbeit häufig CPU-gebundene Vorgänge wie Modelltraining und Datenvorverarbeitung umfasst. Diese Änderung ermöglicht es Python-Code, alle verfügbaren CPU-Kerne gleichzeitig in einem einzigen Prozess zu nutzen, was möglicherweise zu erheblichen Geschwindigkeitsverbesserungen führt.

Um die Auswirkungen zu veranschaulichen, werden in dem Artikel mehrere Leistungsvergleiche vorgestellt:

  • Primzahlen finden: Ein Multithread-Skript sah dramatisch aus 10-fache Leistungssteigerungwobei die Ausführungszeit von 3,70 Sekunden im Normal-Python auf nur 0,35 Sekunden in der GIL-freien Model sank.
  • Mehrere Dateien gleichzeitig lesen: Eine E/A-gebundene Aufgabe, die einen Thread-Pool zur Verarbeitung von 20 großen Textdateien nutzte, battle beendet 3-mal schnellerund dauerte 5,13 Sekunden, verglichen mit 18,77 Sekunden mit dem Standarddolmetscher.
  • Matrixmultiplikation: Ein benutzerdefinierter Multithread-Matrixmultiplikationscode erlebte ebenfalls einen Fehler 10-fache Beschleunigungwobei die GIL-freie Model in 4,56 Sekunden fertig battle, verglichen mit 43,95 Sekunden für die Standardversion.

Allerdings habe ich auch erklärt, dass die GIL-freie Model kein Allheilmittel für die Python-Codeentwicklung ist. Überraschenderweise lief eine Multiprozessorversion des Matrixmultiplikationscodes mit Normal-Python schneller (4,49 Sekunden) als mit dem GIL-freien Construct (6,29 Sekunden). Dies unterstreicht die Bedeutung des Testens und Benchmarkings spezifischer Anwendungen, da der Aufwand für das Prozessmanagement in der GIL-freien Model manchmal deren Vorteile zunichte machen kann.

Ich habe auch den Vorbehalt erwähnt, dass nicht alle Python-Bibliotheken von Drittanbietern mit GIL-freiem Python kompatibel sind, und eine URL angegeben, unter der Sie eine Liste inkompatibler Bibliotheken anzeigen können.

[ad_2]

]]>
https://chatgpz.de/machine-learning/python-3-14-und-das-ende-der-gil/feed/ 0 13278