- lsr adalah program pengganti
ls(1) baru yang dikembangkan dengan memanfaatkan ourio, pustaka IO berbasis io_uring
- Dibandingkan
ls dan alat alternatif yang ada (eza, lsd, uutils ls), kecepatan eksekusi perintahnya sangat tinggi, dan jumlah system call-nya lebih dari 10x lebih sedikit
- Dengan memproses semua IO utama seperti pembukaan direktori,
stat, dan lstat secara asinkron dan batch dengan io_uring, performa dimaksimalkan. Semakin banyak file, semakin cepat keunggulannya terlihat
- StackFallbackAllocator milik Zig digunakan untuk meminimalkan pemanggilan
mmap saat alokasi memori
- Dibangun secara statis tanpa dynamic linking, sehingga ukuran executable-nya bahkan lebih kecil daripada
ls lama
Pengenalan dan signifikansi
- Proyek lsr adalah alat listing direktori cepat yang memanfaatkan io_uring sebagai pengganti perintah
ls biasa
- Dibandingkan
ls, eza, lsd, dan uutils ls, alat ini menunjukkan kinerja unggul dalam kecepatan eksekusi dan penggunaan system call
- Sebisa mungkin menjalankan banyak IO secara langsung dengan pustaka io buatan sendiri, ourio
- Melalui benchmark, lsr membuktikan performa cepat dan kualitasnya bahkan di lingkungan dengan file dalam jumlah besar
Hasil benchmark
- Menggunakan
hyperfine untuk mengukur waktu eksekusi tiap perintah pada direktori yang berisi n file biasa
lsr -al mencatat waktu eksekusi yang jauh lebih singkat dibanding ls/alat alternatif pada rentang 10–10.000 file
- Contoh: pada 10.000 file, lsr mencatat 22,1ms, mengungguli
ls lama (38,0ms), eza (40,2ms), lsd (153,4ms), dan uutils ls (89,6ms) sebagai yang tercepat
- Agregasi system call dilakukan dengan
strace -c
lsr -al: mempertahankan jumlah call yang sangat rendah, dari minimum 20 kali (n=10) hingga maksimum 848 kali (n=10.000)
ls mencapai maksimum 30.396 kali (n=10.000), lsd 100.512 kali, dan alternatif lain juga berada di kisaran ribuan hingga ratusan ribu
- Dalam kondisi yang sama, lsr mencapai efisiensi terbaik dengan jumlah syscall setidaknya 10x lebih sedikit
Struktur dan cara implementasi lsr
- Program berjalan dalam 3 tahap: parsing argumen, pengumpulan data, dan output data
- Semua IO terjadi pada tahap kedua, yaitu pengumpulan data, dan semua akses file/pengambilan informasi yang memungkinkan diproses dengan io_uring
- Pembukaan direktori target,
stat, lstat, serta pengambilan informasi waktu/pengguna/grup semuanya dijalankan berbasis io_uring
stat diproses secara batch untuk memangkas jumlah system call secara drastis
- Dengan Zig StackFallbackAllocator, memori 1MB dialokasikan lebih dulu untuk meminimalkan system call tambahan seperti
mmap
Build statis dan optimasi
- Karena merupakan build statis penuh tanpa dynamic linking libc, overhead eksekusinya sangat kecil
- Dibanding GNU
ls, ukuran build ReleaseSmall lsr lebih kecil, yaitu 138,7KB vs 79,3KB
- Namun, lsr tidak mendukung locale (bahasa/wilayah).
ls biasa memiliki overhead untuk mendukung berbagai bahasa
Analisis system call dan isu performa
lsd memanggil clock_gettime lebih dari 5 kali per file; alasannya tidak jelas (diduga untuk pengukuran timing internal, dll.)
- Pekerjaan sorting mengambil porsi besar dari keseluruhan proses (sekitar 30%)
uutils ls efisien dari sisi system call, tetapi melambat pada pemrosesan sorting
- Hanya dengan mengadopsi io_uring saja, terlihat potensi peningkatan performa yang revolusioner di lingkungan IO berbeban tinggi seperti server
Kesimpulan
- Waktu pengembangannya pun tidak lama, dan efek optimasi syscall melebihi ekspektasi
- lsr adalah pengganti
ls eksperimental yang sekaligus mencapai kecepatan tinggi, sedikit system call, dan ukuran ringkas
- Sangat cocok untuk lingkungan dengan file dalam jumlah besar atau sistem yang mengutamakan IO berperforma tinggi
- Meski ada keterbatasan fitur seperti tidak adanya dukungan locale, hasilnya tetap inovatif baik dalam praktik maupun benchmark
1 komentar
Komentar Hacker News
Mengungkapkan bahwa dirinya adalah penulis proyek tersebut, sekaligus membagikan tulisan pengantar tentang
lsrberbasis io_uring yang bisa dibaca di sinils(1)sangat cepat karena desainnya sederhana, tetapi setelah ditambah berbagai fitur, virtual file system (VFS), beragam charset, dukungan warna, dan lain-lain, akumulasi biaya kecil itu membuatnya melambat. Menurutnya ini diskusi yang menarik tentang biaya abstraksi yang ditangani io_uringtim(tautan pengantar), hasilnya mungkin akan lebih baik daripada hyperfine. Karena ditulis dengan Nim, ini bisa jadi tantangan, tetapi lucu juga bahwa namanya mirip, meski kebetulanlibevringbuatannya sendiri juga masih tahap awal, jadi ia terbuka untuk menggantinya dengan ourio bila perlu. Menurutnya, jika proyek berbasis Zig mendukung binding C/C++, itu akan berguna saat bermigrasi dari C/C++ ke ZigPenasaran bagaimana performa lsr pada server NFS, terutama dalam kondisi jaringan yang buruk. Sudah jelas bahwa penggunaan blocking POSIX syscall pada layanan jaringan yang tidak stabil adalah kelemahan desain NFS. Seberapa jauh io_uring bisa meredakan masalah ini juga menarik untuk diamati
ctrl+ckadang tidak mempan. Secara teori, opsi mountintrmendukung penghentian dengan meneruskan sinyal ke operasi pada server jarak jauh yang sedang berjalan, tetapi di Linux ini sudah lama dihapus (dan sekarang pada dasarnya hanya ada opsisoft) (referensi1, referensi2(dukungan FreeBSD))Menarik bahwa meskipun jumlah pemanggilan syscall berkurang 35 kali, peningkatan kecepatannya hanya sekitar 2 kali
Proyek ini lebih menarik sebagai contoh pemanfaatan io_uring untuk keuntungan performa jangka panjang yang diharapkan, atau sebagai tutorial penggunaannya. Dibanding alat yang sudah ada seperti eza, ia tidak merasa ada motivasi praktis yang kuat mengapa ini dibutuhkan. Kalau menjalankan daftar 10 ribu file bedanya 40ms vs 20ms, rasanya dalam sekali eksekusi orang tidak akan merasakan perbedaannya
lsr memang bagus, tetapi dukungan pewarnaan dan ikon lebih unggul di eza. Ia memasang
eza --icons=always -1, jadi file musik (.opus, dll.) otomatis tampil dengan ikon dan warna, sedangkan di lsr hanya terlihat sebagai file biasa. Meski begitu, lsr jelas terasa sangat cepat dan mudah di-patch. Ia juga berharap cat dan utilitas lain dibuat dengan pendekatan seperti ini, menganggap penggunaan tangled.sh dan atproto menarik, dan merasa Zig lebih mudah didekati pemula dibanding Rustbatadalah pengganticatmodern (tautan ke bat)Ia penasaran kenapa tidak semua alat CLI memakai io_uring. Saat menghubungkan nvme ke usb 3.2 gen2, dengan alat biasa kecepatannya 740MB/s, sedangkan dengan alat berbasis aio atau io_uring bisa naik sampai 1005MB/s. Menurutnya ini juga terkait strategi queue length dan pengurangan lock
#ifdef, sehingga adopsi teknologi baru yang spesifik platform/versi menjadi lambat. Sekarang ia merasa keuntungan kompatibilitas antar berbagai platform posixy tidak lagi sebesar duluDengan strace terlihat bahwa lsd memanggil clock_gettime sekitar 5 kali per file. Ia tidak tahu pasti penyebabnya; mungkin untuk menghitung “berapa menit/jam/hari yang lalu” untuk tiap timestamp, atau mungkin warisan dari library lama
clock_gettimesebenarnya bukan syscall sungguhan, melainkan diproses lewat vDSO (lihatman 7 vDSO). Mungkin saja Zig tidak memanfaatkan struktur iniAgak melenceng dari topik, tetapi ia ingin tahu pengalaman nyata atau angka benchmark tentang seberapa besar io_uring mengurangi overhead latensi socket dalam satuan mikrodetik dibanding LD_PRELOAD pada lingkungan 10G NIC di server enterprise kelas tinggi seperti Mellanox 4 atau 5. Tampaknya efek keduanya tidak saling menumpuk, jadi kalau ada pengalaman langsung ia ingin mendengar angkanya
Karena io_uring tidak mendukung getdents, keuntungan yang benar-benar terasa muncul pada bulk stat (misalnya
ls -l). Ia merasa sayang karena akan bagus bila pemrosesan getdents bisa dibuat asinkron dan diproses tumpang tindihMenurutnya lucu bahwa ada ikon untuk ekstensi
.mjsdan.cjs, tetapi tidak ada untuk ekstensi file seperti.c,.h, atau.sh