InhaltsverzeichnisKlicke auf den Link, um zur gewünschten Stelle zu navigieren
Dieser Inhalt wurde automatisch aus dem Ukrainischen übersetzt.
Zunächst müssen wir klären, was JIT und YJIT sind und ob wir sie brauchen. In dieser Notiz werde ich den Prozess der Aktualisierung von Ruby beschreiben (da YJIT nur zusammen mit Ruby installiert wird, wenn das entsprechende Flag gesetzt ist). Wir werden die Geschwindigkeit von Ruby und Ruby mit YJIT testen.
Was sind JIT und YJIT?
JIT (Just-In-Time) Kompilierung in Ruby ist eine Technologie, die den Ruby-B bytecode in nativem Maschinencode direkt während der Programmausführung umwandelt. Der Einsatz von JIT kann die Ausführungsleistung des Programms erheblich steigern, da nativer Maschinencode schneller ausgeführt wird als interpretierter Bytecode. Ruby verwendet die YARV (Yet Another Ruby VM) virtuelle Maschine, die den geschriebenen Ruby-Code in Bytecode umwandelt, bevor er ausgeführt wird. Die Hinzufügung von JIT zu diesem Prozess ermöglicht es, einige Teile des Codes dynamisch zur Laufzeit zu kompilieren, was die Ausführung des Codes beschleunigt und die Serverlast reduziert.
YJIT ist ein neuer JIT-Kompilierer, der seit Version 3.1 in Ruby integriert ist. YJIT verwendet die sogenannte "faule" JIT-Kompilierung, bei der die Kompilierung nur für "heiße" Ausführungspfade erfolgt, die häufig ausgeführt werden. Dies reduziert die Kosten für die Kompilierung von Code, der selten ausgeführt wird, und sorgt für Leistungssteigerungen dort, wo sie am dringendsten benötigt werden.
YJIT erhöht die Ausführungsgeschwindigkeit von Programmen, ohne dass wesentliche Änderungen am Code selbst erforderlich sind. YJIT ist das Ergebnis des Versuchs, die Leistung von Ruby durch JIT-Kompilierung zu optimieren, während Stabilität und Kompatibilität mit bestehenden Programmen gewahrt bleiben.
Überprüfen, ob YJIT aktiviert ist
Mein lokales Setup - macOS, rbenv und brew. Lokal überprüfen wir die Ruby-Version und ob YJIT aktiviert ist:
Terminal:
ruby -v ruby 3.2.1
Rails-Konsole:
irb(main):003:0> RubyVM::YJIT.enabled?
(irb):3:in `<main>': uninitialized constant RubyVM::YJIT (NameError)
RubyVM::YJIT.enabled?
^^^^^^
Das heißt, derzeit hat Ruby kein YJIT.
Messung der Ausführungsgeschwindigkeit von Ruby ohne YJIT
Wir werden ein Skript erstellen, das die Fibonacci-Sequenz berechnet. Ich habe ein wenig gegoogelt und ChatGPT gefragt, wie man am besten einfaches Benchmarking macht, und das ist die gängigste Variante.
Wir erstellen eine Datei benchmark.rb mit folgendem Code:
require 'benchmark'
def fibonacci(n)
return n if n <= 1
fibonacci(n - 1) + fibonacci(n - 2)
end
puts Benchmark.measure {
fibonacci(40)
}
Wir führen es aus:
ruby ~/Desktop/benchmark.rb
Und mein Ergebnis derzeit (ohne YJIT):
8.309469 0.000711 8.310180 (8.320920)
Ruby mit YJIT installieren
Derzeit habe ich Ruby 3.2.1 (rbenv). Ich muss dieselbe Version installieren, aber bereits mit YJIT. Also fangen wir an.
Haftungsausschluss: Jeder hat sein eigenes Setup. Das angegebene Beispiel ist nur mein Fall.
Die offizielle Dokumentation besagt, dass YJIT benötigt:
- Ein C-Compiler wie GCC oder Clang
- GNU Make und Autoconf
- Den Rust-Compiler rustc und Cargo (wenn Sie im Entwicklungs-/Debug-Modus bauen möchten)
- Die Rust-Version muss >= 1.58.0 sein.
Von all dem muss ich nur Rust installieren (Cool, oder? Die Programmiersprache Rust wird als Compiler verwendet).
Wir installieren Rust mit brew:
brew install rust
Das kann eine Weile dauern (~10 Minuten).
In .zshrc muss das folgende Flag hinzugefügt werden:
export RUBY_CONFIGURE_OPTS="--enable-yjit"
Ohne das Flag wird Ruby ohne YJIT installiert (standardmäßig ist es deaktiviert). Das ist ein wichtiger Punkt.
Wir starten das Terminal neu, damit es RUBY_CONFIGURE_OPTS übernimmt.
Wir installieren Ruby (technisch gesehen wird rbenv install 3.2.1 mit dem Flag --enable-yjit ausgeführt):
\W $ rbenv install 3.2.1 rbenv: /Users/user/.rbenv/versions/3.2.1 already exists continue with installation? (y/N) y
Nach der Installation überprüfen wir, ob YJIT funktioniert und führen Benchmarks für die Datei benchmark.rb durch.Hier gibt es einen Punkt. YJIT ist selbst wenn es zusammen mit Ruby installiert wird - deaktiviert.
Fügen Sie dieses Flag hinzu, damit Ruby mit YJIT gestartet wird:
export RUBY_YJIT_ENABLE=true
Dann sollten wir +YJIT bei der Überprüfung von ruby -v sehen
ruby -v ruby 3.2.1 (2023-02-08 revision 31819e82c8) +YJIT [x86_64-darwin23]
irb RubyVM::YJIT.enabled? => true
YJIT funktioniert. Jetzt testen wir weiter.
ruby ~/Desktop/benchmark.rb
Und wir erhalten:
1.624351 0.000245 1.624596 (1.626251)
Das heißt, der Unterschied in der Ausführungsgeschwindigkeit des Skripts beträgt 5,11 Mal:
8.309469/1.624351=5,1155624616
Technisch gesehen ist das ein ziemlich großer und signifikanter Geschwindigkeitsupgrade für Ruby. Ich habe nur eine Option aktiviert, auf der Kompilierebene erhalten wir eine sehr starke Optimierung. YJIT ist bereits produktionsbereit und kann auf Produktionsservern verwendet werden, zum Beispiel für Ruby on Rails-Anwendungen. Zum Beispiel bietet Heroku an, YJIT mit nur einem Befehl zu aktivieren:
heroku config:set RUBYOPT="--enable-yjit"
Dieser Beitrag hat noch keine Ergänzungen vom Autor.