- zig build kini secara internal dipisah menjadi proses configurer dan maker, dan graf build yang dibuat oleh
build.zig diserialisasi menjadi file konfigurasi biner
- Proses induk menyimpan file konfigurasi ke cache dan mengompilasi maker secara asinkron dalam mode Release; maker hanya perlu dikompilasi sekali ke cache global untuk tiap versi Zig
- Saat pengguna mengubah
build.zig, seluruh sistem build tidak lagi ikut dikompilasi, sehingga beban waktu untuk menambahkan fitur seperti --watch, --fuzz, dan --webui berkurang
- Waktu eksekusi rata-rata
zig build --help turun dari 150ms menjadi 14.3ms, dan siklus CPU, jumlah instruksi, serta referensi cache juga turun 94~96%
- Sebagian besar API tetap kompatibel, tetapi pengamatan langsung terhadap
b.args digantikan oleh addPassthruArgs(), dan Zig 0.17.0 dijadwalkan hadir dalam beberapa minggu
Perubahan struktur sistem build
- Branch besar telah di-merge, dan internal
zig build dipisah menjadi proses configurer dan proses maker
- Pada struktur lama, file
build.zig dan seluruh implementasi sistem build dikompilasi sebagai satu proses besar mode Debug, lalu build.zig membangun graf build di memori dan “build runner” mengeksekusinya
- Pada struktur baru,
build.zig dikompilasi sebagai proses configurer mode Debug yang kecil, dan graf build diserialisasi menjadi file konfigurasi biner
- Proses induk
zig build mendeteksi file konfigurasi, menyimpannya ke cache untuk eksekusi berikutnya, dan mengompilasi maker yang bertugas mengeksekusi graf build secara asinkron dalam mode Release
- Setelah file konfigurasi dan kompilasi maker siap, maker dijalankan dengan menerima file konfigurasi tersebut; berkat cache global, maker hanya perlu dikompilasi sekali untuk tiap
zig version
Dampak peningkatan kecepatan
- Tujuan utamanya adalah meningkatkan kecepatan
zig build, dan saat pengguna mengubah build.zig, seluruh sistem build tidak lagi ikut dikompilasi
- Ini makin penting agar waktu
zig build tidak ikut bertambah meskipun fitur sistem build bertambah dengan hadirnya --watch, --fuzz, dan --webui
- Jika dinilai tidak ada perubahan, logika
build.zig tidak perlu dijalankan ulang dan konfigurasi sebelumnya bisa dipakai kembali
- Misalnya, walaupun
-freference-trace ditambahkan ke baris perintah zig build, logika build.zig tidak akan dijalankan ulang tanpa perlu
- Karena proses yang benar-benar mengeksekusi graf build dikompilasi dengan optimisasi aktif, tahap eksekusinya juga menjadi lebih cepat
Hasil benchmark
- Waktu eksekusi rata-rata
zig build --help turun dari 150ms pada struktur lama menjadi 14.3ms pada struktur baru
- Waktu wall-clock turun 90.4% dari
150ms ke 14.3ms, dan siklus CPU turun 95.9% dari 593M ke 24.1M
- Jumlah instruksi turun 95.6% dari
995M ke 43.7M, dan referensi cache turun 94.3% dari 25.8M ke 1.46M
- RSS puncak turun 7.4% dari
84.8MB ke 78.5MB
- Perbedaan terbesar berasal dari perubahan pendekatan: sebelumnya logika
build.zig dijalankan pada setiap perintah zig build, sekarang konfigurasi serial hasil cache bisa digunakan kembali
Dampak pada alat dan kompatibilitas
- Alat pihak ketiga seperti ZLS bisa mendapat manfaat dengan mengonsumsi file konfigurasi yang telah diserialisasi, alih-alih mem-fork dan memelihara build runner
- Mekanisme internal berubah besar, tetapi dari sudut pandang API sebagian besar tetap kompatibel
- Pengecualian dirangkum dalam perubahan yang dicatat pada PR yang di-merge
Perubahan breaking utama
- Perubahan yang kemungkinan paling sering ditemui banyak pengguna adalah dihapusnya pola yang mengamati
b.args secara langsung
- Kode lama:
if (b.args) |args| {
run_cmd.addArgs(args);
}
run_cmd.addPassthruArgs();
- Dengan perubahan ini, skrip build tidak lagi bisa mengamati argumen tersebut, sehingga satu kemampuan dihapus
- Sebagai gantinya, perubahan pada argumen itu tidak lagi mengharuskan skrip build dibangun ulang dari sumber
Pengujian dan jadwal rilis
- Pengguna yang ingin memengaruhi arah Zig dapat menaikkan proyek mereka ke versi pengembangan untuk mencoba perubahan baru dan memberi masukan
- Zig
0.17.0 dijadwalkan rilis dalam beberapa minggu
- Karena belum sempat diuji lebih awal, sekalipun build rusak di
0.17.0, masih ada cukup kesempatan agar perbaikannya masuk ke tag 0.17.1
1 komentar
Komentar Hacker News
Saya sempat memigrasikan sebagian kode ke Zig 0.16.0, dan hasilnya cukup memuaskan
Bagian yang terdampak memang cukup banyak, tetapi perubahannya sendiri bagus dan tampak mengarah ke masa depan bahasa yang lebih cerah
Khususnya, mekanisme I/O baru memungkinkan kode yang efisien dengan bentuk yang rapi, baik untuk implementasi single-thread, multi-thread, maupun event loop
Kalau belum mencoba Zig lagi sejak 0.16.0, saya sangat menyarankan untuk melihatnya. Catatan rilis kali ini sangat panjang
https://ziglang.org/download/0.16.0/release-notes.html
Setahu saya malah lebih lambat dibanding sebelumnya
Saya berharap di rilis-rilis berikutnya masalah “target dispatch diketahui saat compile time tapi tetap dinamis” bisa diperbaiki sehingga kehilangan efisiensi berkurang
Saya berasumsi bahwa saat
io.asyncdipanggil pada implementasi I/O berbasis event loop, itu secara internal memulai sesuatu seperti “task”, dan future adalah handle-nyaBagian yang tidak saya pahami adalah saat
future.await(io)dipanggil. Apakah implementasi I/O entah bagaimana menangguhkan fungsi saat ini lalu melanjutkannya kembali ketika future selesai? Kalau begitu, apakah itu berarti semua fungsi di Zig adalah stackless coroutine?.use_llvm = truedi build ZigSetelah memakai Zig selama beberapa bulan, saya jadi yakin ini adalah bahasa yang hebat untuk membuat tool
Enak dipakai saat ingin bebas mengutak-atik ide secara kasar, dan di setiap titik macet biasanya sudah ada solusi nyaman yang dipikirkan oleh para pembuatnya
Tapi tetap tidak memaksa cara penggunaan bahasa yang “benar”
Sekarang ini jadi bahasa default saya untuk “ngoprek di garasi”
Buat saya itu masalah produktivitas yang cukup besar
Bahasa default saya untuk “ngoprek di garasi” adalah Python. Sintaksnya ringan, enak dipakai tanpa banyak gangguan, standard library-nya kaya, dan kalau kurang biasanya ada paketnya
Apa kelebihan Zig?
Setelah menonton video wawancara Andrew Kelley, saya jadi ingin belajar Zig: https://www.youtube.com/watch?v=iqddnwKF8HQ
Jawaban Andrew bagus, tetapi suasana keseluruhannya terasa terlalu menjilat
Saya ingin mencoba Zig, tetapi bahasanya masih berubah terlalu cepat
Karena setiap rilis mematahkan API, sulit untuk sekaligus mengikuti proses belajar bahasa, debugging build system, dan mengimplementasikan hal yang benar-benar ingin dibuat
Setelah melihat wawancara JetBrains, saya memang ingin mencoba lagi, tetapi mungkin saya akan menunggu sampai 1.0 keluar
Sudah lama saya memikirkan ide yang saya sebut pemrograman ganda
Maksudnya, stack hanya terdiri dari dua bahasa: satu bahasa tingkat tinggi dan satu bahasa tingkat rendah
Struktur kerjanya adalah menulis sebanyak mungkin dengan bahasa tingkat tinggi, lalu turun ke bahasa tingkat rendah hanya saat perlu
Masalahnya, kalau Anda belum benar-benar sangat mahir dengan bahasa tingkat rendah itu, besar kemungkinan Anda harus membiasakan diri lagi dengannya sebelum bisa mengerjakan bagian low-level
Karena itu C++ atau Rust jadi lebih sulit dipakai daripada C, sehingga bagi saya C menjadi pilihan default. Tapi C juga punya masalah-masalah yang sudah terkenal
Zig tampaknya bisa mengisi titik yang pas itu karena cukup sederhana untuk mudah dipakai lagi setelah jeda panjang, sambil tetap punya alat modern yang mempermudah pemrograman
Sebisa mungkin kerjakan sebanyak mungkin di bahasa tingkat rendah, lalu naik ke bahasa tingkat tinggi hanya saat kenyamanannya memang sepadan dengan biayanya
Roc memungkinkan hal ini. Semua program memiliki platform yang ditulis dalam bahasa tingkat rendah, dan program Roc menggunakan API yang diekspos oleh platform tersebut
https://www.roc-lang.org/
Tentu saja, bagaimana menyeimbangkan high-level dan low-level itu pilihan masing-masing
Modelnya diimplementasikan dengan Cython, sementara API untuk pengguna diberikan dalam Python
Sekarang saya melakukan semuanya dengan Rust, dan terutama berkat type system-nya yang mirip OCaml, saya belum menemukan hal yang tidak bisa saya lakukan
Lua memang dirancang sebagai bahasa embedded, jadi bagus untuk interoperabilitas, dan sekaligus cukup high-level sehingga mudah dipakai
Ada alasan mengapa Factorio memakai Lua sebagai bahasa scripting
Salah satu hal yang saya suka dari pengembangan Zig adalah mereka mencurahkan upaya yang luar biasa besar pada tooling dan feedback loop pengembang, alih-alih sekadar menambah fitur bahasa
Bahasa baru masih bisa bertahan walau untuk sementara belum punya satu fitur tertentu
Tetapi jauh lebih sulit bertahan kalau compile, link, dan pembaruan dependensi terasa lambat setiap saat
Fokus untuk membuat siklus pengembangan berada di level milidetik, bukan detik, tampak seperti taruhan jangka panjang yang bagus
Saya kaget melihat kalimat “berencana merilis 0.17.0 dalam beberapa minggu”
Bukankah 0.16 memakan waktu lebih dari setahun?
Saya tidak menyangka rilis 0.17 akan secepat ini, jadi sangat senang mengetahuinya hari ini
Kedengarannya seperti kabar baik. Waktu kompilasi Zig sudah sangat bagus, dan perubahan ini sepertinya akan membuatnya lebih baik lagi
Ini jelas target yang penting, dan milestone untuk mencapainya juga sudah jelas, tetapi dalam praktiknya sulit menyebut waktu tunggu yang menyakitkan saat kompilasi pertama proyek kosong atau saat ZLS dibangun ulang setelah
direnv allowsebagai sesuatu yang “sangat bagus”zig test file.zig -OReleaseSafe, di komputer saya tetap butuh beberapa detik.Setiap kali file diubah, waktu yang sama terus dibutuhkan. Saya memakai 0.16 atau master, jadi bukan karena toolchain yang usang, dan ini juga di lingkungan Linux.
Bahasa Zig sendiri benar-benar menyenangkan untuk ditulis, tetapi menurut saya kompiler dan standard library-nya belum dikembangkan dengan pendekatan yang cukup konservatif.
Saat mulai dari hello world, mungkin masalah seperti ini tidak terasa, tetapi kalau ingin melakukan fuzz testing atau benchmark, kita jadi ingin menjalankan binary yang dioptimalkan.
Lalu kompilasi kode yang relatif kecil pun terasa sangat menjengkelkan.
Sebagai perbandingan, saya menganggap Zig jauh lebih baik sebagai bahasa dibanding Rust/C++/C, tetapi masalah seperti ini pada praktiknya hampir tidak pernah muncul di Rust/C++/C. Untuk C/C++, asumsinya memakai clang/gcc/ninja dan sejenisnya.
Di komputer yang sama, dengan Ninja/Python/clang saya bisa menyiapkan, membangun (-O2 atau -O3), dan menguji proyek C++ sekitar 10 ribu baris hanya dalam 200ms
Akan sangat bagus kalau Zig punya mekanisme resmi untuk mengekspor stub library Linux.
Kemampuan cross-compilation Zig dan kemampuannya menargetkan versi glibc sesuka hati itu benar-benar seperti sihir.
Saya memanfaatkan “sihir” ini dalam build system C++ terpisah, tetapi untuk mendapatkan stub library itu dari Zig saya harus mencari jalan memutar.
Akan bagus kalau ini tersedia sebagai output resmi
Memangnya apa alasan sampai ingin memakai ini alih-alih Node.js dan TypeScript?
Kalau tidak butuh tetes terakhir dari performa serta tata letak dan kontrol memori, memakai Zig justru punya lebih banyak kekurangan.
Untuk pekerjaan CRUD, tugas “enterprise”, atau website, keunggulan Zig hampir tidak terasa
Program Zig yang sudah dikompilasi bisa hanya berukuran beberapa KB tanpa dependensi.
Akses array yang ditulis dalam bahasa level rendah bisa dioptimalkan dengan SIMD dan paralelisasi, dan untuk pekerjaan yang sama bisa beberapa orde magnitudo lebih cepat daripada JavaScript.
Perbedaannya besar untuk pemrosesan teks, manipulasi gambar, pemrosesan video, hashing, dan sebagainya.
Alasan untuk tidak memakai JavaScript pada dasarnya nyaris tak terbatas