Ripgrep: Alat pencarian yang lebih cepat daripada grep, ag, Git grep, dan lainnya (2016)
(blog.burntsushi.net)- ripgrep (
rg) adalah alat pencarian baris perintah berbasis Rust yang menggabungkan kenyamanan pencarian kode ala The Silver Searcher dengan performa mentah setara GNU grep, dan menyediakan biner untuk Linux, Mac, dan Windows - Dalam 25 benchmark, tidak ada alat yang secara jelas mengungguli
ripgrepdalam performa maupun akurasi, baik untuk pencarian pada satu file besar maupun direktori berskala besar; biaya dukungan Unicode juga tetap kecil - Dengan pemrosesan
.gitignore, pengecualian default untuk file tersembunyi dan biner, filter tipe file, dukungan opsional PCRE2, pencarian berbagai encoding dan file terkompresi, hingga filter prapemrosesan, alat ini memperluas cakupan penggunaan praktis alat pencarian kode - Perbedaan eksperimen pada repositori kernel Linux dan OpenSubtitles2016 sangat dipengaruhi oleh optimasi literal, pencarian multi-pola SIMD Teddy, Aho-Corasick, metode decoding UTF-8, penghitungan baris, dan biaya pemrosesan
.gitignore - Saat mencari banyak file kecil secara paralel, memory map bisa menjadi lebih lambat, sedangkan pada satu file besar bisa menguntungkan; karena itu
ripgrepmenggunakan pencarian dengan buffer perantara dan pencarian memory map secara terpisah sesuai situasi
Posisi yang dituju ripgrep
ripgrepadalah alat pencarian baris perintah yang menargetkan sekaligus kenyamanan alat pencarian kode dan performa alat sejenisgrep- Pembandingnya adalah
GNU grep,git grep,The Silver Searcher (ag),Universal Code Grep (ucg),The Platinum Searcher (pt), dansift - Inti yang ingin diverifikasi benchmark ada tiga
- Tidak ada alat yang secara jelas lebih unggul daripada
ripgrep, baik dalam pencarian satu file maupun direktori berskala besar - Menyediakan dukungan Unicode dengan benar tanpa menuntut biaya performa besar
- Saat mencari banyak file sekaligus, memory map umumnya bisa menjadi lebih lambat, bukan lebih cepat
- Tidak ada alat yang secara jelas lebih unggul daripada
- Penulis adalah pembuat
ripgrepdan engine regular expression yang mendasarinya, serta menyatakan bahwa benchmark dapat dipilih secara selektif dan memiliki bias
Fitur dan perilaku default
- Nama file executable
ripgrepadalahrg - Pencarian default menjelajahi direktori saat ini secara rekursif, menghormati
.gitignore, serta melewati file tersembunyi dan file biner .rgignorejuga didukung, dan pola.rgignorememiliki prioritas di atas.gitignore- Dengan
-u,-uu, dan-uuu, cakupan dapat diperluas untuk mengabaikan file ignore, menyertakan file tersembunyi, dan menyertakan file binerrg -uuumirip dengangrep -a -r
- Mendukung filter tipe file
rg -tpy foo: hanya mencari file Pythonrg -Tjs foo: mengecualikan file JavaScript- Aturan tipe file baru dapat ditambahkan dengan
--type-add
- Berbagai fitur
grepjuga disediakan- Output konteks
- Pencarian beberapa pola
- Highlight warna
- Dukungan Unicode penuh
- Engine regular expression default tidak mendukung look-around dan backreference, tetapi jika engine PCRE2 dipilih dengan
-P, fitur tersebut dapat digunakan - Juga mendukung deteksi otomatis sebagian UTF-16 dan penetapan encoding berbasis
-E/--encoding- Termasuk UTF-16, latin-1, GBK, EUC-JP, Shift_JIS, dan lainnya
- Dengan
-z/--search-zip, mendukung pencarian file terkompresi seperti gzip, xz, lzma, bzip2, dan lz4 - Juga mendukung filter prapemrosesan arbitrer seperti ekstraksi teks PDF, dekompresi tambahan, dekripsi, dan deteksi encoding otomatis
Alasan untuk tidak menggunakannya
- Jika portabilitas dan ketersediaan di mana saja adalah prioritas utama, grep yang sesuai standar dan terpasang luas lebih cocok
- Jika bergantung pada fitur tertentu atau bug yang ada di alat lain,
ripgrepmungkin tidak cocok - Dalam beberapa kasus edge performa, alat lain bisa bekerja lebih baik
- Jika tidak dapat diinstal atau tidak ada dukungan platform, alat ini juga tidak bisa digunakan
Struktur kerja alat sejenis grep
- Alat pencarian secara garis besar melalui tiga tahap
- Mengumpulkan file yang akan dicari
- Melakukan pencarian sebenarnya
- Menampilkan hasil
- Karena alat sejenis
grepharus mampu mencari file besar dengan baik, performa engine regular expression menjadi penting - Alat sejenis
ackharus memproses penjelajahan direktori rekursif dan penerapan aturan ignore seperti.gitignoredengan cepat ripgrepmencoba menggabungkan kedua pendekatan tersebut- Engine regular expression yang cepat
- Pencarian paralel
- Pemfilteran target pencarian
Pengumpulan file dan pemrosesan ignore
- Pada alat sejenis
ack, penting untuk cepat menentukan file mana di direktori saat ini yang akan dicari - Performa traversal direktori dipengaruhi oleh jumlah panggilan
statyang tidak perlu ripgrepmenggunakan iterator direktori rekursif yang bertujuan meminimalkan system call- Pemrosesan
.gitignorememiliki biaya- Harus mencari file ignore di setiap direktori
- Harus mengompilasi pola ignore
- Harus menerapkan pola ke semua kandidat path
- Repositori kernel Linux memiliki 4.640 direktori dan 178 file
.gitignore ripgrepberupaya mendukung semantik.gitignoresecara lebih lengkap, dan memberi prioritas pada pola cocok yang didefinisikan paling baruucgbisa lebih cepat karena menggunakan aturan glob berbasis whitelist alih-alih.gitignore, tetapi dapat melewatkan file dengan ekstensi yang tidak dikenal
Perbedaan engine regular expression
- Engine regular expression secara umum terbagi menjadi dua jenis
- Berbasis backtracking: kaya fitur, tetapi pada input tertentu bisa melambat hingga waktu eksponensial
- Berbasis finite automata: fiturnya bisa terbatas, tetapi memberikan jaminan waktu linear terhadap panjang teks yang dicari
- Engine per alat adalah sebagai berikut
- GNU grep,
git grep: engine internal berbasis finite automata ripgrep: library regex Rust, berbasis finite automataag,ucg: berbasis PCRE dengan backtrackingpt,sift: library regex Go, berbasis finite automata
- GNU grep,
agdanucgdapat terekspos pada perilaku backtracking kasus terburuk karena penggunaan PCRE- Pola contoh
(a*)* cdapat menimbulkan masalah pada alat berbasis PCRE, tetapi alat pembanding benchmark lainnya menanganinya tanpa masalah
Optimasi literal dan SIMD
- Dalam pencarian string sederhana, optimasi pencarian literal bisa menjadi lebih penting daripada engine regular expression
- Boyer-Moore adalah algoritme pencarian substring klasik, dan dapat memanfaatkan rutin seperti
memchruntuk menemukan posisi kandidat dengan cepat - Implementasi
memchrsering memeriksa 16 byte sekaligus dengan instruksi SIMD, dan dapat mencapai throughput beberapa GB/detik - Library regex Rust secara agresif mengekstrak literal prefix dan suffix dari pola
foo|bar(a|b)c[ab]foo[yz](foo)?bar(foo)*bar(foo){3,6}
- Jika seluruh regular expression dapat diurai menjadi satu literal atau alternation literal, engine regular expression inti sama sekali bisa tidak digunakan
ripgrepjuga mengekstrak inner literal dengan memanfaatkan karakteristik output hasil per baris- Contoh: pada
\w+foo\d+, temukanfooterlebih dahulu lalu verifikasi hanya baris kandidat dengan regular expression
- Contoh: pada
- Untuk pencarian beberapa literal, GNU grep menggunakan algoritme mirip Commentz-Walter, sedangkan regex Rust menggunakan algoritme Aho-Corasick atau Teddy SIMD
- Teddy adalah algoritme pencarian multi-pola berbasis SIMD yang berasal dari Intel Hyperscan, dan merupakan salah satu optimasi utama yang membuat
ripgrepmengungguli GNU grep
Metode pencarian: menghindari pencarian per baris
- Implementasi naif membaca file baris demi baris dan menerapkan pola pada tiap baris, tetapi pada sebagian besar pencarian, match jarang terjadi sehingga ini tidak efisien
- Alat pencarian biasanya mencari buffer byte besar sekaligus
- Memetakan file dengan memory map
- Membaca seluruh file ke memori
- Melakukan pencarian bertahap dengan buffer perantara berukuran tetap
ripgrep, GNU grep, dangit grepmendukung pencarian bertahap sehingga dapat diterapkan baik pada file maupun stream- Pencarian bertahap sulit diimplementasikan
- Menghitung nomor baris
- Menangani kasus ketika buffer berakhir di tengah baris
- Menangani baris panjang
- Menangani invert match
- Menangani output konteks di sekitar match
ripgrepmenggunakan pencarian bertahap meskipun kompleks secara implementasi, dan dalam benchmark menunjukkan hasil lebih cepat daripada memory map saat mencari banyak file kecil
Output dan paralelisme
- Dalam pencarian paralel, jika setiap thread langsung menulis output, hasil dari file yang berbeda bisa tercampur
- Semua alat pencarian kode paralel menulis hasil pencarian ke buffer perantara di memori, lalu hanya tahap output yang diserialkan
- Cara ini memungkinkan thread pencarian menjalankan pencarian sebenarnya secara paralel
- Kekurangannya, penggunaan memori bisa menjadi besar pada kasus seperti file 2GB yang setiap barisnya cocok
ripgrepmenulis langsung kestdouttanpa buffer perantara saat mencari daristdinatau satu file
Metodologi benchmark
- Benchmark dibagi berdasarkan masalah pengguna akhir
- Pencarian repositori kode berskala besar
- Pencarian satu file berukuran besar
- Pola pencarian cenderung berfokus pada literal sederhana, alternation, dan regex ringan
- Karena perilaku default tiap alat berbeda, kondisi seperti nomor baris, Unicode,
.gitignore, dan whitelist coba diselaraskan untuk perbandingan yang adil - Versi yang menjadi target benchmark adalah sebagai berikut
ripgrepv0.1.2- GNU grep v2.25
git grepv2.7.4- commit
agcda635, PCRE 8.38 - commit
ucg487bfb, PCRE 10.21 JIT - commit
pt509368 - commit
sift2d175c
ackdikecualikan karena saat itu jauh lebih lambat daripada alat lain- Runner benchmark adalah
benchsuiteyang membutuhkan Python 3.5 atau lebih baru, dan disertakan dalam repositoriripgrep - Setiap perintah menjalankan warm-up 3 kali sebelum pengukuran agar korpus masuk ke OS page cache
- Setiap perintah diukur 10 kali, lalu rata-rata dan simpangan bakunya dicatat
- Lingkungan eksekusi adalah Amazon EC2
c3.2xlarge, Ubuntu 16.04, Xeon E5-2680 2.8GHz, memori 16GB, SSD 80GB - Log konfigurasi, hasil ringkasan, dan CSV mentah juga dipublikasikan
Hasil pencarian kode kernel Linux
- Benchmark pencarian kode dijalankan pada repositori kernel Linux yang sudah dibangun, commit
d0acc7 - Alasan memakai repositori kernel yang sudah dibangun adalah karena artefak build yang tertinggal di repositori dapat memengaruhi relevansi hasil pencarian dan performa
- Pada
linux_literal_default, pencarian literal sederhanaPM_RESUMEmemperlihatkan perbedaan perilaku default tiap alatrgmenghormati.gitignoredan melewati file tersembunyi serta bineragdanptjuga serupa, tetapi menghitung jumlah barisucgtidak membaca.gitignoredan melakukan pencarian berbasis whitelistsiftsecara default mencari hampir semuanyagit grepmemiliki keuntungan karena memperoleh kumpulan file pencarian dari git index
- Menghormati
.gitignoremeningkatkan relevansi hasil, tetapi bisa menimbulkan biaya performa - Pada
linux_literal,rg (whitelist)menunjukkan performa yang hampir sama denganucg, sedangkanrg (ignore)berada pada level yang mirip dengangit grep rg (ignore) (mmap)danag (ignore) (mmap)menjadi lebih lambat karena penggunaan memory map, dan dalam kondisi yang samarg (ignore)jauh lebih cepat- Di mesin lokal pun versi memory map lebih lambat, tetapi selisihnya lebih kecil dibandingkan di EC2
Unicode dan pencarian case-insensitive
- Pada
linux_literal_casei,ptmenjadi jauh lebih lambat karena memproses-isebagai(?i)di Go regexp sifttidak terlalu melambat karena memakai cara mengubah pola dan blok pencarian menjadi huruf kecil, tetapi optimasi ini hanya menangani kapitalisasi ASCII sehingga tidak akurat untuk penanganan kapitalisasi Unicoderipgrepmengubah pencarian case-insensitive menjadi kombinasi literal bila memungkinkan, lalu memakai Teddy untuk menemukan posisi kandidat dengan cepat- Pencarian
\wAhpadalinux_unicode_wordmemeriksa apakah\wyang sadar Unicode menangkap hasil sepertiµAh - Hanya
rgdangit grepyang bisa mengaktifkan/menonaktifkan Unicode, sedangkanag,pt,sift, danucgmenggunakan\wkhusus ASCII git grepmengalami biaya performa besar saat dukungan Unicode diaktifkan, tetapiripgrephampir tidak mengalami penurunan performaripgrepmemasukkan decoding UTF-8 ke dalam finite state machine sehingga mencocokkan langsung pada string byte UTF-8 tanpa tahap decoding terpisah
Perbedaan menurut kompleksitas regex
- Pada regex dengan suffix literal seperti
[A-Z]+_RESUME,rgdanucgmenggunakan_RESUMEuntuk menemukan kandidat dengan cepat - Pada alternation literal seperti
ERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVT,ripgrepmemakai Teddy dan bisa saja tidak menggunakan mesin regex inti sama sekali - Pada alternation case-insensitive pun
ripgrepmembuat prefix kombinasi huruf besar/kecil, mencari kandidat dengan Teddy, lalu hanya memverifikasi kandidat dengan regex penuh - Dalam pencarian
\p{Greek}, hanya Rust regex dan Go regex yang mendukung properti Unicode tersebut, danrgjauh lebih cepat daripadaptdansift - Dalam pencarian case-insensitive
\p{Greek},sifttidak dapat melaporkan match, danpttidak menangani kapitalisasi Unicode dengan benar - Pada pola tanpa literal seperti
\w{5}\s+..., performa mesin regex terlihat langsungrgtergolong cepat bahkan dengan dukungan Unicode aktifgit grepmembayar biaya besar saat dukungan Unicode aktif- Unicode DFA menangani kumpulan status NFA yang jauh lebih besar daripada ASCII DFA; angka contohnya sekitar 250 status NFA untuk ASCII dan sekitar 77.000 status NFA untuk Unicode
Pencarian satu file berukuran besar
- Benchmark satu file menggunakan sampel OpenSubtitles2016
- Sampel bahasa Inggris sekitar 1GB
- Sampel bahasa Rusia sekitar 1,6GB
- Di area ini, performa mesin regex dan optimasi literal menjadi lebih penting
- Pada
subtitles_literal,rgpaling cepat untuk pencarianSherlock HolmesmaupunШерлок Холмс ripgrepmencoba memilih byte yang jarang muncul dari literal untuk digunakan padamemchr- Implementasi Boyer-Moore standar biasanya memakai byte terakhir untuk pencarian kandidat
rgmencoba memilih byte yang lebih jarang agar dapat melompati lebih lama dalam loop yang dioptimalkan SIMD
- Pada UTF-8, banyak karakter dalam pola bahasa Rusia dimulai dengan
\xD0atau\xD1, sehingga pencarian byte pertama bisa tidak efisien rgmenggunakan tabel frekuensi 256 byte yang telah dihitung sebelumnya untuk lebih memilih byte yang lebih jarang daripada\xD0dan\xD1- Pada satu file besar, karena memory map hanya perlu dibuat sekali, pencarian memory map
rgsekitar 25% lebih cepat daripadarg (no mmap)
Unicode dan alternation pada satu file
- Pada
subtitles_literal_casei,rgtetap cepat sambil menangani pencarian case-insensitive Unicode dengan benar - GNU grep membayar biaya besar pada pencarian case-insensitive Unicode
- Dalam pencarian case-insensitive bahasa Rusia,
grep (ASCII)tampaknya pada dasarnya mengabaikan-i, sedangkanagmelaporkan 0 match - Pada
subtitles_alternate, pencarian alternation beberapa nama tokoh menunjukkanrgpaling cepat baik untuk bahasa Inggris maupun Rusia - Pada alternation bahasa Inggris,
rgsekitar satu orde magnitudo lebih cepat daripada GNU grep - Pada
subtitles_alternate_casei,rgmenjadi jauh lebih lambat daripada sebelumnya, tetapi masih mengungguli alat lain untuk bahasa Inggris - Dalam kasus ini, jumlah kandidat literal menjadi terlalu banyak untuk ditangani Teddy, sehingga
rgberalih ke Aho-Corasick ripgrepmenggunakan Aho-Corasick “advanced” berbasis transition table yang melakukan satu transisi untuk setiap byte input
Inner literal dan pola tanpa literal
- Pola seperti
\w+\s+Holmes\s+\w+dirancang untuk menghindari optimisasi literal prefix·suffix, tetapi tetap dapat memanfaatkan literal internalHolmes ripgrepdan GNU grep melakukan optimisasi inner literalripgrepmemanfaatkanregex-syntaxdari Rust regex untuk mengekstrak literal dari AST pola- Pada versi Rusia
\w+\s+Холмс\s+\w+, hanya alat yang mendukung Unicode dengan benar yang dapat menghasilkan hasil yang bermakna - Pada pola panjang tanpa literal sama sekali seperti
\w{5}\s+...,rgtermasuk yang tercepat untuk bahasa Inggris, sementara versi GNU grep yang mendukung Unicode memakan waktu lebih dari 90 detik untuk bahasa Inggris dan lebih dari 4 menit untuk bahasa Rusia sehingga dikeluarkan ripgrepmempertahankan dukungan Unicode sekaligus mendapatkan performa dengan memasukkan decoding UTF-8 ke dalam DFA
Benchmark tambahan
everythingadalah pengujian tidak realistis yang mencocokkan semua baris di repositori Linux dengan.*rgmelaporkan 22.065.361 baris dalam 1,081 detikagdanpttampaknya memiliki batas kecocokan karena tidak melaporkan semua baris
nothingadalah pengujian yang menerapkan invert match pada.*sehingga tidak melaporkan baris apa punrgmencatat 0,302 detik, sementaragit grepmencatat 0,905 detikptdanucgtidak mendukung invert search
contextmencetak konteks 2 baris di sekitarSherlock Holmesdari korpus subtitle bahasa Inggrisrg0,612 detik dansift0,717 detik, jadi keduanya miripucgtidak mendukung fitur tersebut
hugemencariSherlock Holmesdi seluruh subtitle bahasa Inggris berukuran 9,3 GBrgmencatat 1,786 detik, GNU grep 5,119 detik, dansift3,047 detikucghanya melaporkan 1.543 baris pada kondisi penghitungan baris sehingga menghasilkan hasil yang keliru, dan diduga bermasalah saat mencari file berukuran lebih dari 2 GB
Kesimpulan
ripgreptidak selalu memenangkan semua benchmark dalam pencarian repositori kernel Linux, tetapi sulit mengatakan ada alat lain yang jelas lebih unggul dalam performa dan akurasigit grepbisa unggul beberapa milidetik pada sebagian kasus sederhana, tetapi ketika pola menjadi kompleks atau Unicode dibutuhkan, ada kasus ketikaripgrepunggul jauh- Performa pencarian kode
ripgrepdipengaruhi oleh faktor-faktor berikut- Traversal direktori cepat yang menargetkan pemanggilan
statseminimal mungkin - Pencocokan glob
.gitignoremenggunakanRegexSet - Distribusi pekerjaan melalui Chase-Lev work stealing queue
- Pilihan untuk tidak memakai memory map saat mencari banyak file kecil
- Engine regex yang cepat
- Traversal direktori cepat yang menargetkan pemanggilan
- Dalam pencarian file tunggal,
ripgrepmenjadi yang tercepat atau unggul dengan selisih besar pada semua benchmark utama - Performa file tunggal dipengaruhi oleh
memchrberbasis sparse byte, Teddy SIMD, Aho-Corasick, dan DFA dengan decoding UTF-8 bawaan - Pada benchmark yang membutuhkan fitur Unicode, hanya
rg, GNU grep, dangit grepyang menunjukkan dukungan bermakna, dan GNU grep sertagit grepumumnya membayar biaya performa besar - Memory map merugikan dalam pencarian paralel atas banyak file kecil pada Linux x86_64, menguntungkan dalam pencarian satu file besar, dan dapat memiliki penalti tambahan di lingkungan VM
1 komentar
Komentar Hacker News
Memang cepat, dan saya jadi terus merekomendasikan kombinasi fzf
Saya memakainya sebagai fungsi PowerShell yang mula-mula mencari dengan
ripgrep, lalu menambahkan pencarian fuzzy di atas hasil file+teksnya, dan menampilkan konteks denganbatDi proyek yang mencampur banyak repositori, ini sangat cepat untuk mempersempit pencarian saat “saya tahu ada di suatu tempat, tapi tidak tahu lokasi atau namanya yang tepat”
Pendekatan ini berasal dari https://github.com/junegunn/fzf/blob/master/ADVANCED.md, dan meski tidak dipakai semuanya, tetap layak dibaca sekilas untuk mencari ide
fzfBukan cuma file teks, tapi juga bisa melakukan pencarian fuzzy pada banyak format file seperti PDF dan zip
Detailnya ada di https://github.com/phiresky/ripgrep-all/wiki/fzf-Integration
Caranya memilih hasil
rgdenganfzf, lalu mem-parsing file dan nomor baris yang dipilih, kemudian membukanya dengan$EDITOR +"${linenumber}" "$file"Seperti menggiling kopi dengan tangan alih-alih memakai penggiling listrik
fzf, kita bisa memilih banyak file untuk ditambahkan ke Git sambil melewati sebagian fileJika menambahkan
fza = "!git ls-files -m -o --exclude-standard | fzf -m --print0 | xargs -0 git add"ke[alias]digitconfig, makagit fzaakan menampilkan daftar file yang sudah dimodifikasi atau belum ditambahkan, dan kita bisa men-toggle item dengan spasi sambil lanjut ke item berikutnyaAlias ini dan fzf+fd cukup mempercepat beberapa bagian alur kerja
Ada juga panduan yang merangkum hal-hal untuk dimasukkan ke pengaturan zsh di macOS: https://gist.github.com/aclarknexient/0ffcb98aa262c585c49d4b...
ripgrepdengan cara yang hampir samaSaya memakainya sebagai titik awal untuk mempersempit file atau proyek dalam codebase yang punya ratusan repositori, lalu menggali lebih dalam setelah itu
Di Emacs saya memakai
ripgrepdengan project.el dan paket dumb-jumpMungkin ini bukan cara yang paling populer, tapi pengalaman keseluruhannya cukup memuaskan
Cukup instal
dumb-jumpdenganpackage-installdan atur(add-hook 'xref-backend-functions #'dumb-jump-xref-activate)Saat mencari definisi identifier di proyek Python dengan
M-.atauC-u M-.,dumb-jumpakan menjalankan perintahrgsesuai proyek dan tipe file saat ini, lalu menampilkan hasilnya di buffer Xrefagjuga didukung, dan jikaagataurgtidak ada maka akan kembali kegrep, yang tentu bisa lambat saat mencari di seluruh home directoryripgrepcukup mudah dipakaiPaket eksternal tidak wajib, dan untuk memakai pengganti
grepyang lambat di direktori besar, cukup setel(setq xref-search-program 'ripgrep)Setelah itu pencarian proyek seperti
C-x p g foo RETakan dijalankan di proyek saat ini dalam bentukrg -i --null -nH --no-heading --no-messages -g '!*/' -e fooHasilnya muncul di buffer Xref, sehingga nyaman memakai tombol seperti
n,p,RET,C-ountuk pindah ke kecocokan berikutnya/sebelumnya, lompat ke sumber, atau menampilkannya di jendela terpisahripgrep, menurut saya regex itu tampaknya tidak perlu flag --pcre2, meski saya belum menjalankannya sendiriAssertion
\bkedua dan ketiga juga sepertinya bisa dihapus, sedangkan yang pertama mungkin memang diperlukanripgrepdan juga punya bindingevil-collection, jadi enak dipakai: https://github.com/Wilfred/deadgrepItu situasi yang dulunya akan membuat saya memakai
rgrepHal yang menarik adalah pencarian VS Code sekarang juga berjalan dengan
ripgrepmelalui wrapper Node.jshttps://www.npmjs.com/package/@vscode/ripgrep
ripgreptidak bisa dipasangKita bisa menemukan biner
rgdi dalam path instalasi VS. Setidaknya itu memungkinkan di lingkungan kerja Windows sayaSaya sudah memakai
ripgrepsekitar 2 tahun, dan sekarang ini jadi alat yang tidak tergantikanAlasan utama saya beralih dari
grepadalah kemudahan penggunaanSecara default ia menghormati aturan
.gitignoredan melewati file/direktori tersembunyi serta file biner, jadirg search_term directoryjauh lebih baik daripada perintahgreppadanannya, dan peningkatan kecepatan itu bonus tambahanSaat kecocokannya terlalu panjang sampai terminal jadi berantakan, saya sering memakai opsi -M seperti
-M 1000-Mbenar-benar luar biasaSangat berguna terutama untuk mengabaikan hasil dari file minified yang tidak ingin dilihat, dan opsi -g seperti
-g *.csuntuk mencari hanya file dengan ekstensi tertentu juga bagusFakta bahwa ini adalah biner portabel yang dapat dijalankan mandiri juga berguna; saat bekerja di mesin baru, kita tinggal meletakkan executable-nya dan menjadikan
grepsebagai alias kerg, jadi ketika mengetikgrepseperti biasa, yang berjalan sebenarnyargIni mungkin masih benar pada 2023, tetapi masalahnya adalah alat pengganti
grepyang diparalelkan, misalnyaripgrepatauag, terlalu cepat dibandinggreplama sehingga selisih kecepatan kecil di antara mereka sulit dijadikan pembeda.Saya memakai
agdi dalam Emacs pada codebase 900 ribu baris, dan di Ryzen Threadripper 2950X 16-core hasilnya praktis instan.Saya tidak merasa perlu mengurangi waktu “kurang dari 1 detik” menjadi “sedikit lebih kurang dari 1 detik”.
Sifat utama alat-alat
grepbaru bukan lagi kecepatan, dan sebaiknya dievaluasi serta dibandingkan dengan cara lain.agpunya performance cliff yang cukup besar, dan itu juga terlihat di tulisan blog tersebut.Namun workload tiap orang berbeda, jadi dalam beberapa kasus perbedaan performa mungkin tidak penting.
900 ribu baris bukan ukuran yang terlalu besar, dan untuk kueri sederhana sebagian besar alat sejenis
grepyang tidak naif akan memprosesnya dengan sangat cepat.Jika dilihat dari kriteria pembanding lain,
agnyaris dalam status pemeliharaan minimum, dan tampaknya sempat hampir dihapus dari Debian lalu diselamatkan seseorang: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999962Tulisan blog itu juga membandingkan dukungan Unicode, dan
agpada praktiknya tidak punya dukungan Unicode. Ini mungkin tidak penting bagi semua orang, tetapi cukup sebagai kriteria pembanding non-performa.Waktu pencarian berlangsung selama waktu yang dibutuhkan untuk memuat file dari disk, dan setelah itu selisihnya sulit menjadi bermakna.
Jika file sudah ada di cache, waktu untuk menjelajahi filesystem dan mengetik perintah lebih dominan daripada waktu pencarian, jadi perbedaan performa juga sulit punya arti.
Judulnya perlu (2016).
Ini tulisan pengumuman asli, bukan informasi baru.
“Ripgrep – A new command line search tool” https://news.ycombinator.com/item?id=12564442 (740 points | Sept 23, 2016 | 209 comments) — ada juga diskusi soal kecepatan
“Ripgrep is faster (2016)” https://news.ycombinator.com/item?id=17941319 (98 points | Sept 8, 2018 | 40 comments)
Ini tidak lebih cepat daripada
qgrep.Cara kerja keduanya sangat berbeda, dan
qgrepberbasisre2, tetapi kecepatannya datang dari adanya indeks.Pada repositori file besar, menggunakan
qgrepdan indeks lebih masuk akal daripada memindai semua file setiap kali, jadi saya penasaran kenapa orang-orang melupakan opsiqgrep.Namun jika butuh pencocokan multi-baris di UTF-8, saya rasa
ripgrepharus beralih ke library PCRE2 lain sehingga tidak akan secepat itu.ripgrep, memang benar bahwaqgrepdiuntungkan karena memakai indexing dibanding alat yang tidak melakukan indexing.Sebagai gantinya, indeks harus disiapkan dan dipelihara, jadi UX-nya tidak sesederhana “langsung jalankan pencarian”.
Alasan orang tidak memakai
qgrepmirip dengan alasan mereka tidak memakairipgrepkarena “buat saya grep saja sudah cukup cepat”.Pada target pencarian kecil, sering kali orang tidak merasakan perbedaan kecepatan antara
ripgrepdangrep, atau antaraqgrepdanripgrep.Jika
ripgrepbisa menyelesaikan pencarian kernel Linux dalam waktu di bawah 100ms, apakah cukup merepotkan untuk beralih ke alat berbasis indeks dalam penggunaan interaktif standar akan bergantung pada situasinya, tetapi biasanya tidak.Saya memang pernah memikirkan ide menambahkan indexing ke
ripgrep: https://github.com/BurntSushi/ripgrep/issues/1497Dan pencarian multi-baris tidak memerlukan PCRE2. Mesin regex bawaan juga mendukung Unicode, dan dukungan pencarian multi-baris tetap ada bahkan jika dibangun tanpa PCRE2.
Setelah beralih dari
ripgrepke ugrep, saya tidak pernah menoleh lagi.Kecepatannya mirip, tetapi ada fuzzy matching, TUI yang berguna untuk code review, dan juga bisa mencari di dalam PDF maupun arsip terkompresi.
Juga praktis karena secara opsional bisa memakai sintaks pencarian Google.
https://ugrep.com
ripgrep, tetapi belakangan saya menemukanugrepkarena fitur yang tidak dimilikiripgrep, yaitu pencarian di dalam file zip.Bisa mencari tanpa mengekstraknya ke disk.
Saya menangani korpus arsip yang berisi jutaan file teks kecil, dan bagus sekali karena tidak perlu mengekstrak semuanya ke filesystem. Beberapa filesystem kesulitan pada skala seperti ini.
Terima kasih untuk kedua alat ini, dan terima kasih kepada masing-masing pembuatnya.
grep, sebagian besar hasilnya malah akan mencoba menjual sesuatu kepada saya.ugrepdanripgrepbertengkar di Reddit selama beberapa tahun.Misalnya https://www.reddit.com/r/programming/comments/120wqvr/ripgre...
Ini cuma soal alat open source, jadi rasanya agak aneh.
fzf.Bagi saya, sulit mengalahkan kemampuan konfigurasi dan fleksibilitas
fzf.Fitur pembunuhnya tampaknya adalah kompatibilitas dengan opsi command line
grepyang sudah ada.Cukup menyenangkan karena tidak perlu mempelajari kumpulan opsi yang benar-benar baru.
Bertanya-tanya mengapa
greptidak digantikan atau diperbaikiTopik ini juga sekarang terasa sudah agak lama
Hal-hal seperti inersia, kompatibilitas, resistensi terhadap perubahan, dan dilema inovator. Bukan bermaksud mengatakan ini secara negatif, karena semuanya juga berlaku pada saya
Untuk soal kompatibilitas, lihat FAQ: https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#pos...
Kursinya nyaman, cocok dengan lingkungan kerja di sekitar saya, dan tidak ada alasan kuat untuk menggantinya lalu menyesuaikan semuanya lagi
Analogi itu hanya berlaku sampai pada fakta bahwa ada kursi seperti Razer di dekat sini yang sudah dipakai untuk menaruh pakaian
xyz, harus menerima argumen ini, dan harus berperilaku persis seperti ini”ripgrepyang bisa dipakaiJika yang dimaksud adalah mengganti perintah
grepitu sendiri dengan utilitas lain, rasanya terlalu banyak yang akan rusak dibanding nilai yang didapatOrang yang ingin
greplebih cepat bisa memakai alat lain, dan orang yang memakaigreplama bisa tetap memakainya, jadi kondisi sekarang sudah mendekati idealgrepadalah alat serbaguna untuk mencari teks di semua jenis file, dan sudah tertanam dalam standar UNIXSebagian programmer memakainya untuk mencari dalam source code, tetapi orang lain memakainya untuk pencarian teks yang tidak berkaitan dengan source code atau di dalam skrip, dan mereka berharap alat itu sama sekali tidak pernah crash
Sebaliknya,
ripgrepadalah alat yang lebih khusus dan memiliki opini kuat, yang terutama dirancang untuk menelusuri repositori source codeTidak banyak ruang untuk membuat pencarian teks serbaguna menjadi lebih cepat. Anda bisa memakai
mmap()tetapi ada risiko crash pada file yang terpotong, bisa juga mempercepatnya dengan mengurangi kemampuan ekspresi regex, dan bahkan bisa membuang dukungan semua locale dan charset lalu meng-hardcode hanya UTF-8/UTF-16, tetapi itu tidak seharusnya dilakukanSetelah mencarinya di Portage, sepertinya ada juga versi yang menangani dokumen lain seperti PDF dan doc
https://github.com/phiresky/ripgrep-all