Die Veröffentlichung von Ruby 3.3.0 hat stattgefunden, einer leistungsstarken, dynamischen objektorientierten Programmiersprache, die sich durch hohe Effizienz in der Softwareentwicklung auszeichnet und die besten Eigenschaften von Perl, Java, Python, Smalltalk, Eiffel, Ada und Lisp vereint. Der Code des Projekts wird unter den Lizenzen BSD ("2-clause BSDL") und "Ruby" verbreitet, wobei Letztere auf die neueste Version der GPL verweist und vollständig mit GPLv3 kompatibel ist.
Wesentliche Verbesserungen:
- Im Hauptsatz ist der Prism-Parser enthalten, der als C-Bibliothek libprism implementiert wurde und im CRuby-Interpreter sowie als Ruby-Gem-Paket genutzt wird, das eine öffentliche API für die abwärts rekursive Analyse von Ruby-Code bereitstellt und anstelle des Ripper-Parsers in Arbeitsprojekten eingesetzt werden kann. Zu den Vorteilen von Prism zählen gute Portabilität und flexible Fehlerbehandlung im Code. Um den neuen Parser zu aktivieren, kann die Option „ruby --parser=prism“ oder die Umgebungsvariable RUBYOPT="--parser=prism" verwendet werden. Für die Analyse von Code in Ihren Programmen stehen die Methoden Prism.parse(source) für die Erzeugung einer AST-Darstellung des Codes, Prism.parse_comments(source) zur Extraktion von Kommentaren aus dem Code und Prism.parse_success?(source) zur Überprüfung auf Fehler im Code zur Verfügung.
- Anstelle des externen Bison-Pakets zur Generierung von Parsern wird das Projekt Lrama verwendet, das eine Implementierung des LALR-Algorithmus in Ruby bereitstellt und Bison-kompatible Grammatikdefinitionen (parse.y) unterstützt, die in CRuby verwendet werden. Es implementiert erweiterte Funktionen wie Fehlerbehandlung und parametrisierte Regeln (?, *, +).
- Es wurde eine erhebliche Leistungsoptimierung des JIT-Compilers YJIT vorgenommen, der von den Entwicklern der E-Commerce-Plattform Shopify im Rahmen einer Initiative zur Steigerung der Leistung von Ruby-Anwendungen, die das Framework Rails nutzen und sehr viele Methoden aufrufen, entwickelt wurde. Im Gegensatz zum zuvor verwendeten JIT-Compiler MJIT verwendet der neue YJIT die Versionierung der grundlegenden Blöcke (LBBV – Lazy Basic Block Versioning) anstelle der vollständigen Bearbeitung von Methoden und wird als integrierter JIT-Compiler in Rust implementiert. Dank LBBV kompiliert JIT zunächst nur den Anfang der Methode und kompiliert den verbleibenden Teil später, nachdem während der Ausführung die Typen der verwendeten Variablen und Argumente bestimmt wurden.
Beim Testen der Ausführung des Optcarrot-Emulators übertrifft die Leistung mit YJIT die Ausführung über den Interpreter mehr als dreimal. In der neuen Version gibt es eine Registerzuweisung für Stackoperationen der virtuellen Maschine, der Umfang der kompilierten Aufrufe mit optionalen Argumenten wurde erweitert, es wurde eine Inline-Entfaltung für Basis- und spezialisierte Methoden implementiert, und es wurden spezielle Optimierungen für die Operationen „Integer#*“, „Integer#!=“, „String#!=“, „String#getbyte“, „Kernel#block_given?“, „Kernel#is_a?“, „Kernel#instance_of?“ und „Module#===“ hinzugefügt. Die Geschwindigkeit der Kompilierung wurde erheblich erhöht.
Der Speicherverbrauch für die Speicherung von Metadaten wurde deutlich reduziert, und es wird ein kompakterer Code für die ARM64-Architektur generiert. Der Garbage Collector Code („—yjit-code-gc“), der nicht verwendeten generierten Maschinencode dynamisch freigibt, aber während der Garbage Collection zu einer Leistungseinbuße führt, ist standardmäßig deaktiviert. Die Methode RubyVM::YJIT.enable wurde hinzugefügt, um die Aktivierung von YJIT zur Laufzeit zu steuern, ohne dass ein bestimmter Befehlszeilenparameter oder eine Umgebungsvariable erforderlich ist. Die Statistiken, die bei Angabe der Option „—yjit-stats“ ausgegeben werden, wurden erweitert. Die Modi zur Leistungsprofilierung (—yjit-perf) und zur Nachverfolgung (—yjit-trace-exits) wurden hinzugefügt.
- Ein neuer JIT-Compiler namens RJIT wurde vorgeschlagen, der vollständig in Ruby geschrieben ist und MJIT ersetzt. Im Gegensatz zu Letzterem benötigt RJIT bei der Verwendung keinen C-Compiler und unterstützt nur die Architektur x86-64 und UNIX-ähnliche Plattformen.
- Der M:N-Thread-Planer wurde hinzugefügt, um die Overheadkosten für die Erstellung und Verwaltung von Threads zu minimieren, indem eine begrenzte Anzahl von Betriebssystem-Threads zur Verarbeitung von Threads im Ruby-Code verwendet wird. Standardmäßig werden 8 Betriebssystem-Threads verwendet (dies kann über die Umgebungsvariable RUBY_MAX_CPU geändert werden). Die Verwendung des M:N-Planers kann Kompatibilitätsprobleme mit C-Extensions verursachen, weshalb er standardmäßig für die Haupt- (main) Ractor-Klasse deaktiviert ist, aber für nicht-haupt (non-main) aktiviert ist. Um den M:N-Planer zwangsweise zu aktivieren, sollte die Umgebungsvariable RUBY_MN_THREADS=1 gesetzt werden.
- Die Funktionen der interaktiven Berechnungsumgebung IRB (REPL, Read-Eval-Print-Loop) wurden erweitert. Es wurde der Debugging-Modus irb:rdbg hinzugefügt, der die gleichen Möglichkeiten wie der pry-byebug-Debugger bietet. Unterstützung für die mehrseitige Anzeige der Ausgaben der Befehle ls, show_source und show_cmds wurde hinzugefügt. Experimentelle Unterstützung für die automatische Eingabevervollständigung unter Berücksichtigung der Datentypen wurde implementiert. Es stehen Befehle zur Verfügung, um die Farbe und den Schriftstil zu ändern.
- Der Aufruf der Methode „it“ ohne Argumente in einem Parameterlosen Block wurde als veraltet erklärt (zum Beispiel „[1, 2, 3].each { puts it }“).
- In RubyGems und Bundler wurde eine Warnung aktiviert, wenn in „require“ die gem-Pakete abbrev, base64, bigdecimal, csv, drb, getoptlong, mutex_m, nkf, observer, racc, resolv-replace, rinda und syslog angegeben werden, ohne dass sie im Gemfile oder der gemspec hinzugefügt wurden. In zukünftigen Versionen von Ruby werden diese gem-Pakete in die Standardbibliothek integriert.
- Die Versionen der eingebauten und in die Standardbibliothek integrierten Gem-Module wurden aktualisiert.
Quelle: opennet.ru
