Meningkatkan Performa Ruby: Menulis Ulang C ke Ruby
Perbandingan performa Ruby
- Dalam repositori perbandingan bahasa terbaru, Ruby dinilai lebih cepat daripada R dan Python, tetapi tetap menjadi bahasa paling lambat ketiga.
- Benchmark terdiri dari dua jenis, yaitu "Loops" dan "Fibonacci", yang masing-masing menyoroti loop dan percabangan, overhead pemanggilan fungsi, serta performa rekursi.
Perbandingan performa Ruby dan Node.js
- Pada M3 MacBook Pro, Ruby 3.3.6 membutuhkan 28 detik untuk contoh loop dan 12 detik untuk contoh Fibonacci.
- Node.js membutuhkan sekitar 1 detik untuk kedua contoh tersebut.
- Pada M2 MacBook Air, performa Ruby menjadi lebih buruk.
Makna benchmark
- Benchmark semacam ini sebenarnya mungkin tidak terlalu berarti.
- Python dinilai sebagai bahasa paling lambat, tetapi merupakan bahasa yang paling banyak digunakan di GitHub.
- Bahasa pemrograman memang harus efisien, tetapi kegunaan dan produktivitas bahasa lebih penting daripada performa.
Penerapan YJIT
- Dengan menerapkan YJIT, performa Fibonacci meningkat secara signifikan.
- Pada contoh loop, peningkatan performanya sangat kecil.
Optimasi kode Ruby
Range#each ditulis dalam C sehingga tidak bisa dioptimalkan oleh YJIT.
Integer#times di Ruby 3.3 dipindahkan dari C ke Ruby sehingga bisa dioptimalkan oleh YJIT.
Array#each di Ruby 3.4 juga dipindahkan dari C ke Ruby.
Optimasi Integer#times
Integer#succ berjalan lebih cepat daripada i += 1.
- YJIT mengoptimalkan
Integer#times sehingga performanya meningkat drastis.
Optimasi Array#each
Array#each dipindahkan dari C ke Ruby di Ruby 3.4 sehingga bisa dioptimalkan oleh YJIT.
- Modul
Primitive digunakan untuk mengevaluasi kode C di dalam Ruby.
Repositori Ruby Microbench
- Benchmark dijalankan menggunakan berbagai versi Ruby dan YJIT.
- Ruby 3.4 YJIT menunjukkan peningkatan performa yang besar.
Optimasi range#each
- Performa dapat ditingkatkan dengan mengimplementasikan kelas
Range dalam Ruby murni.
Pustaka standar YJIT
- Tim YJIT sedang meningkatkan performa dengan mengganti kode C menggunakan Ruby.
- Blok
with_yjit digunakan agar implementasi Ruby dipakai saat YJIT diaktifkan.
Penelusuran optimasi YJIT
- YJIT mengubah bytecode Ruby VM menjadi kode mesin untuk mengoptimalkan performa.
- Proses optimasi YJIT dipahami dengan menganalisis kode mesin dari
Integer#succ.
1 komentar
Komentar Hacker News
Contoh loop mengulang 1 miliar kali dan menggunakan loop bersarang. Diduga benchmark ini akan menghabiskan lebih dari 99% waktunya pada dua baris pertama
utidak diketahui saat waktu kompilasi, loop dalam tetap bisa digantikan dengan beberapa instruksiAda penyebutan tentang versi Ruby mendatang; Ruby 3.4.0 dijadwalkan rilis saat Natal tahun ini, dan Ruby 3.5.0 pada Natal tahun depan
Rasa suka pada Ruby masih tetap ada. Terima kasih kepada Matz
Ada PR peningkatan performa untuk
Integer#succpada awal 2024, dan itu membantu memahami alasan penggunaanInteger#succInteger#succdigunakan saat menulis ulang metode loop, dan di interpreteropt_succ (i = i.succ)diproses lebih cepat daripadaputobject 1; opt_plus (i += 1)#succkarena keterbacaan, dan memakainya dua kali di metode#bytespada library UUID agar tetap berada dalam "mode bit slicing" saat membaca kodeBerbagi pengalaman terkait TruffleRuby, yang disebut lebih cepat daripada Node.js dan mendekati Bun atau Golang
Ruby sudah menjadi sangat cepat, dan TruffleRuby bahkan lebih mengesankan
Tidak tahu bahwa YJIT ditulis dalam Rust
Python adalah bahasa paling lambat dalam benchmark, tetapi per Oktober 2024 menjadi bahasa yang paling banyak digunakan di Github
Ada repositori perbandingan bahasa yang lebih lama yang mencakup lebih banyak bahasa
Ini membawa perubahan besar pada solusi Advent of Code, dan hasilnya terlihat sangat mirip