Ripgrep: grep, ag ve Git grep’ten daha hızlı arama aracı (2016)
(blog.burntsushi.net)- ripgrep (
rg), The Silver Searcher tarzı kod arama kolaylığını GNU grep düzeyinde ham performansla birleştiren Rust tabanlı bir komut satırı arama aracıdır; Linux, Mac ve Windows ikililerini sunar - 25 benchmark’ta hem tek bir büyük dosyada hem de büyük dizinlerde aramada
ripgrepten performans ve doğruluk açısından açıkça önde olan bir araç yoktu; Unicode desteğinin maliyeti de düşük tutuldu .gitignoreişleme, gizli ve ikili dosyaları varsayılan olarak hariç tutma, dosya türü filtreleri, isteğe bağlı PCRE2 desteği, birden çok kodlama ve sıkıştırılmış dosyada arama, ön işleme filtreleri gibi özelliklerle kod arama araçlarının pratik kullanım alanını genişletir- Linux çekirdek deposu ile OpenSubtitles2016 deneyleri arasındaki farklar büyük ölçüde literal optimizasyonu, Teddy SIMD çoklu desen araması, Aho-Corasick, UTF-8 çözümleme yöntemi, satır sayma ve
.gitignoreişleme maliyetine bağlıdır - Çok sayıda küçük dosyada paralel arama yaparken bellek eşleme yavaşlayabilir; tek bir büyük dosyada ise avantajlı olabilir. Bu nedenle
ripgrep, duruma göre ara tamponla arama ile bellek eşlemeli aramayı ayrı ayrı kullanır
ripgrep’in hedeflediği konum
ripgrep, kod arama araçlarının kullanım kolaylığı ilegreptürü araçların performansını birlikte hedefleyen bir komut satırı arama aracıdır- Karşılaştırılan araçlar
GNU grep,git grep,The Silver Searcher (ag),Universal Code Grep (ucg),The Platinum Searcher (pt)vesifttir - Benchmark’ların doğrulamaya çalıştığı üç ana nokta vardı
- Hem tek dosyada hem de büyük dizinlerde aramada
ripgrepten açıkça üstün bir araç yoktur - Unicode desteğini düzgün biçimde sunarken büyük bir performans maliyeti gerektirmez
- Birden çok dosyada tek seferde arama yaparken bellek eşleme çoğunlukla daha hızlı değil, daha yavaş olabilir
- Hem tek dosyada hem de büyük dizinlerde aramada
- Yazar,
ripgrepin ve temelindeki düzenli ifade motorunun geliştiricisidir; benchmark’ların seçilmiş olup yanlılık taşıyabileceğini belirtir
Özellikler ve varsayılan davranış
ripgrepin çalıştırılabilir dosya adırgdir- Varsayılan arama, geçerli dizini özyinelemeli olarak tarar,
.gitignorekurallarına uyar ve gizli dosyalar ile ikili dosyaları atlar .rgignoreda desteklenir;.rgignoredesenleri.gitignoredan önceliklidir-u,-uu,-uuuile ignore dosyalarını yok sayma, gizli dosyaları dahil etme ve ikili dosyaları dahil etme kapsamı genişletilebilirrg -uuu,grep -a -rkomutuna benzerdir
- Dosya türü filtrelerini destekler
rg -tpy foo: yalnızca Python dosyalarında ararrg -Tjs foo: JavaScript dosyalarını hariç tutar--type-addile yeni dosya türü kuralları eklenebilir
grepin birçok özelliğini de sunar- Bağlam çıktısı
- Birden çok desenle arama
- Renkli vurgulama
- Tam Unicode desteği
- Varsayılan düzenli ifade motoru look-around ve backreference desteklemez; ancak
-Pile PCRE2 motoru seçilirse bu özellikler kullanılabilir - UTF-16’nın kısmi otomatik algılanmasını ve
-E/--encodingtabanlı kodlama belirtmeyi de destekler- UTF-16, latin-1, GBK, EUC-JP, Shift_JIS vb. dahildir
-z/--search-zipile gzip, xz, lzma, bzip2, lz4 gibi sıkıştırılmış dosyalarda aramayı destekler- PDF metni çıkarma, ek sıkıştırma açma, şifre çözme, otomatik kodlama algılama gibi isteğe bağlı ön işleme filtrelerini de destekler
Kullanmamak için nedenler
- Taşınabilirlik ve her yerde kullanılabilirlik en yüksek öncelikse, standartlara uygun ve yaygın olarak kurulu olan grep uygundur
- Başka araçlarda bulunan belirli bir özelliğe veya hataya bağımlıysanız
ripgrepuygun olmayabilir - Bazı performans sınır durumlarında başka araçlar daha iyi çalışabilir
- Kurulamıyorsa veya platform desteği yoksa kullanılamaz
grep türü araçların çalışma yapısı
- Arama araçları genel olarak üç aşamadan geçer
- Aranacak dosyaları toplama
- Gerçek arama
- Sonuçları yazdırma
greptürü araçlar büyük dosyaları iyi aramak zorunda olduğundan düzenli ifade motoru performansı önemlidiracktürü araçların özyinelemeli dizin taramayı ve.gitignoregibi ignore kurallarını hızlı işlemesi gerekirripgrepiki yaklaşımı birleştirmeye çalışır- Hızlı düzenli ifade motoru
- Paralel arama
- Aranacak hedefleri filtreleme
Dosya toplama ve ignore işleme
acktürü araçlarda, geçerli dizinde hangi dosyaların aranacağını hızlı belirlemek önemlidir- Dizin dolaşma performansı, gereksiz
statçağrılarının sayısından etkilenir ripgrep, en az sistem çağrısını hedefleyen özyinelemeli bir dizin yineleyicisi kullanır.gitignoreişlemenin bir maliyeti vardır- Her dizinde ignore dosyalarının bulunması gerekir
- Ignore desenlerinin derlenmesi gerekir
- Desenlerin tüm aday yollara uygulanması gerekir
- Linux çekirdek deposunda 4.640 dizin ve 178
.gitignoredosyası vardı ripgrep,.gitignoreanlamını daha eksiksiz desteklemeye çalışır ve en son tanımlanan eşleşen desene öncelik verirucg,.gitignoreyerine beyaz liste tabanlı glob kuralları kullandığı için hızlı olabilir; ancak bilinmeyen uzantılı dosyaları kaçırabilir
Düzenli ifade motoru farkları
- Düzenli ifade motorları genel olarak iki sınıfa ayrılır
- Backtracking tabanlı: özellik bakımından zengindir, ancak bazı girdilerde üstel zamanda yavaşlayabilir
- Sonlu otomat tabanlı: özellikleri sınırlı olabilir, ancak aranan metnin uzunluğuna göre doğrusal zaman garantisi sağlar
- Araçlara göre motorlar şöyledir
- GNU grep,
git grep: kendi sonlu otomat tabanlı motorları ripgrep: Rust regex kütüphanesi, sonlu otomat tabanlıag,ucg: PCRE tabanlı backtrackingpt,sift: Go regex kütüphanesi, sonlu otomat tabanlı
- GNU grep,
agveucg, PCRE kullandıkları için en kötü durumdaki backtracking davranışına maruz kalabilir- Örnek desen
(a*)* c, PCRE tabanlı araçlarda sorun yaratabilir; diğer benchmark kapsamındaki araçlar ise bunu sorunsuz işler
Literal optimizasyonu ve SIMD
- Basit dizge aramalarında literal arama optimizasyonu, düzenli ifade motorundan daha önemli hale gelebilir
- Boyer-Moore klasik bir alt dizge arama algoritmasıdır ve aday konumları hızlı bulmak için
memchrgibi rutinlerden yararlanabilir memchruygulamaları çoğu zaman SIMD komutlarıyla tek seferde 16 bayt denetler ve GB/sn düzeyinde iş hacmi sağlayabilir- Rust regex kütüphanesi, desenlerden prefix ve suffix literalleri agresif biçimde çıkarır
foo|bar(a|b)c[ab]foo[yz](foo)?bar(foo)*bar(foo){3,6}
- Düzenli ifadenin tamamı tek bir literal veya literal alternation’a ayrıştırılabiliyorsa çekirdek düzenli ifade motoru hiç kullanılmayabilir
ripgrep, satır bazlı sonuç çıktısı özelliğinden yararlanarak inner literal de çıkarır- Örn.
\w+foo\d+içinde öncefoobulunur, ardından yalnızca aday satırlar düzenli ifadeyle doğrulanır
- Örn.
- Birden çok literal aramasında GNU grep, Commentz-Walter benzeri bir algoritma kullanır; Rust regex ise Aho-Corasick veya Teddy SIMD algoritmasını kullanır
- Teddy, Intel Hyperscan’den çıkan SIMD tabanlı bir çoklu desen arama algoritmasıdır ve
ripgrepin GNU grep’i geçmesini sağlayan temel optimizasyonlardan biridir
Arama yöntemi: satır bazlı aramadan kaçınma
- Saf bir uygulama dosyayı satır satır okur ve her satıra deseni uygular; ancak çoğu aramada eşleşmeler seyrek olduğu için bu verimsizdir
- Arama araçları genellikle büyük bir bayt tamponunu tek seferde arar
- Dosyayı bellek eşleme ile eşlemek
- Dosyanın tamamını belleğe okumak
- Sabit boyutlu bir ara tamponla kademeli arama
ripgrep, GNU grep vegit grep, kademeli aramayı destekler; bu sayede hem dosyalara hem de akışlara uygulanabilir- Kademeli aramanın uygulanması zordur
- Satır numarası hesaplama
- Tamponun satır ortasında bittiği durumları işleme
- Uzun satırları işleme
- Ters eşleşme işlemeyi yönetme
- Eşleşme çevresindeki bağlam çıktısını işleme
ripgrep, uygulama karmaşıklığını göze alarak kademeli arama kullanır ve benchmark’larda çok sayıda küçük dosyada arama yaparken bellek eşlemeye göre daha hızlı sonuçlar gösterir
Çıktı ve paralellik
- Paralel aramada her iş parçacığı doğrudan çıktı verirse farklı dosyalara ait sonuçlar birbirine karışabilir
- Tüm paralel kod arama araçları arama sonuçlarını bellekteki ara tamponlara yazar ve yalnızca çıktı aşamasını seri hale getirir
- Bu yöntem, arama iş parçacıklarının gerçek aramayı paralel olarak yapmasını sağlar
- Dezavantajı, tüm satırların eşleştiği 2 GB’lık bir dosya gibi durumlarda bellek kullanımının artabilmesidir
ripgrep,stdinveya tek dosya aramalarında ara tampon olmadan doğrudanstdout’a yazar
Benchmark metodolojisi
- Benchmark’lar son kullanıcı problemlerine göre ayrılır
- Büyük ölçekli kod deposu araması
- Tek büyük dosya araması
- Arama desenleri basit literal’lere, alternation’a ve hafif düzenli ifadelere ağırlık verir
- Araçların varsayılan davranışları farklı olduğundan, adil karşılaştırma için satır numarası, Unicode,
.gitignore, beyaz liste gibi koşullar eşitlenmeye çalışılır - Benchmark’a alınan sürümler şunlardır
ripgrepv0.1.2- GNU grep v2.25
git grepv2.7.4agcommitcda635, PCRE 8.38ucgcommit487bfb, PCRE 10.21 JITptcommit509368siftcommit2d175c
ack, o dönemde diğer araçlardan çok daha yavaş olduğu için hariç tutuldu- Benchmark çalıştırıcısı, Python 3.5 veya üzerini gerektiren
benchsuite’tir veripgrepdeposuna dahildir - Her komut, ölçümden önce 3 kez warm-up çalıştırılarak derlemin OS page cache’e alınması sağlanır
- Her komut 10 kez ölçülür; ortalama ve standart sapma kaydedilir
- Çalıştırma ortamı Amazon EC2
c3.2xlarge, Ubuntu 16.04, Xeon E5-2680 2.8GHz, 16 GB bellek ve 80 GB SSD’dir - Yapılandırma günlükleri, özet sonuçlar ve ham CSV de yayımlanmıştır
Linux çekirdeği kod arama sonuçları
- Kod arama benchmark’ı, derlenmiş Linux çekirdeği deposunun
d0acc7commit’i üzerinde çalıştırıldı - Derlenmiş çekirdek deposunun kullanılma nedeni, build çıktılarının depoda kalıp arama sonuçlarının ilgililiğini ve performansı etkileyebilmesidir
linux_literal_defaultiçinde basit literalPM_RESUMEaraması, her aracın varsayılan davranışındaki farkları ortaya koyarrg,.gitignore’a uyar ve gizli/binary dosyaları atlaragveptde benzerdir ancak satır sayısını sayarucg,.gitignore’ı okumaz ve beyaz liste temelli arama yaparsiftvarsayılan olarak neredeyse her şeyi arargit grep, aranacak dosya kümesini git index’inden alma avantajına sahiptir
.gitignore’a uymak sonuçların ilgililiğini artırır, ancak performans maliyeti doğurabilirlinux_literaliçinderg (whitelist),ucgile neredeyse aynı performansı gösterdi;rg (ignore)isegit grepile benzer seviyedeydirg (ignore) (mmap)veag (ignore) (mmap), bellek eşleme kullanımı nedeniyle yavaşladı; aynı koşullardarg (ignore)çok daha hızlıydı- Yerel makinede de bellek eşleme sürümü daha yavaştı, ancak fark EC2’ye göre azaldı
Unicode ve büyük/küçük harf duyarsız arama
linux_literal_caseiiçindept,-iseçeneğini Go regexp’in(?i)biçimiyle işlediği için belirgin biçimde yavaşladısift, deseni ve arama bloğunu küçük harfe çevirme yöntemini kullandığı için daha az yavaşladı; ancak bu optimizasyon yalnızca ASCII büyük/küçük harflerini ele aldığından Unicode büyük/küçük harf işleme için doğru değildirripgrep, büyük/küçük harf duyarsız aramayı mümkün olan literal kombinasyonlarına dönüştürür ve Teddy ile aday konumları hızlıca bulurlinux_unicode_wordiçindeki\wAharaması, Unicode farkındalıklı\w’ninµAhgibi sonuçları yakalayıp yakalamadığını kontrol eder- Yalnızca
rgvegit grepUnicode geçişini açıp kapatabiliyordu;ag,pt,siftveucgASCII’ye özgü\wkullanıyordu git grep, Unicode desteği açıldığında büyük performans maliyeti ödedi;ripgrep’te ise performans düşüşü neredeyse yokturipgrep, UTF-8 çözümlemeyi sonlu durum makinesine dahil ederek ayrı bir çözümleme aşaması olmadan doğrudan UTF-8 bayt dizgileri üzerinde eşleştirme yapar
Düzenli ifade karmaşıklığına göre farklar
[A-Z]+_RESUMEgibi literal suffix içeren düzenli ifadelerdergveucg,_RESUME’ı kullanarak adayları hızlıca bulurERR_SYS|PME_TURN_OFF|LINK_REQ_RST|CFG_BME_EVTgibi literal alternation’lardaripgrepTeddy kullanır ve çekirdek düzenli ifade motorunu hiç kullanmayabilir- Büyük/küçük harf duyarsız alternation’da da
ripgrep, büyük/küçük harf kombinasyonu prefix’leri oluşturarak Teddy ile adayları bulur ve yalnızca adayları tam düzenli ifadeyle doğrular \p{Greek}aramasında ilgili Unicode özelliğini yalnızca Rust regex ve Go regex destekliyordu;rg,ptvesift’ten çok daha hızlıydı\p{Greek}büyük/küçük harf duyarsız aramadasifteşleşme raporlayamadı;ptise Unicode büyük/küçük harf işlemeyi doğru yapamadı\w{5}\s+...gibi literal içermeyen desenlerde regex motorunun performansı doğrudan görünür hale gelirrg, Unicode desteği açıkken bile hızlı sayılırdıgit grep, Unicode desteğinde büyük maliyet ödedi- Unicode DFA, ASCII DFA’dan çok daha büyük NFA durum kümeleriyle uğraşır; örnek değerler ASCII için yaklaşık 250, Unicode için yaklaşık 77.000 NFA durumudur
Tek büyük dosya araması
- Tek dosya benchmark’ı OpenSubtitles2016 örneğini kullanır
- İngilizce örnek yaklaşık 1 GB’tır
- Rusça örnek yaklaşık 1,6 GB’tır
- Bu alanda düzenli ifade motoru performansı ve literal optimizasyonu daha önemli hale gelir
subtitles_literaliçindeSherlock HolmesveШерлок Холмсaramalarındargher ikisinde de en hızlıydıripgrep, literal’lerde seyrek bayt seçip bunumemchriçinde kullanmaya çalışır- Standart Boyer-Moore uygulaması genellikle son baytı aday aramada kullanır
rg, daha nadir bir bayt seçerek SIMD optimizasyonlu döngüde daha uzun atlamaya çalışır
- Rusça desenlerde UTF-8’de birçok karakter
\xD0veya\xD1ile başladığından ilk baytı aramak verimsiz olabilir rg, önceden hesaplanmış 256 baytlık frekans tablosunu kullanarak\xD0,\xD1yerine daha nadir baytları tercih eder- Tek büyük dosyada bellek eşlemesini yalnızca bir kez oluşturmak yeterli olduğundan
rg’nin bellek eşlemeli araması,rg (no mmap)’ten yaklaşık %25 daha hızlıydı
Tek dosyada Unicode ve alternation
subtitles_literal_caseiiçinderg, Unicode büyük/küçük harf duyarsız aramayı doğru işlerken hızlı kalır- GNU grep, Unicode büyük/küçük harf duyarsız aramada büyük maliyet öder
- Rusça büyük/küçük harf duyarsız aramada
grep (ASCII),-iseçeneğini fiilen yok sayıyor gibi görünür;agise 0 eşleşme raporlar subtitles_alternateiçinde birden fazla karakter adını içeren alternation aramasındarg, hem İngilizce hem Rusçada en hızlıydı- İngilizce alternation’da
rg, GNU grep’ten yaklaşık bir büyüklük mertebesi daha hızlıydı subtitles_alternate_caseiiçindergönceye göre çok daha yavaşladı, ancak İngilizcede diğer araçların önündeydi- Bu durumda Teddy’nin kaldırabileceğinden fazla literal adayı oluştuğu için
rg, Teddy yerine Aho-Corasick’e geçer ripgrep, transition table tabanlı “advanced” Aho-Corasick kullanarak her giriş baytı için tek bir geçiş yapar
İç literal ve literalsiz desenler
\w+\s+Holmes\s+\w+gibi desenler prefix·suffix literal optimizasyonundan kaçınacak şekilde yapılandırılmış olsa da, içeridekiHolmesliteralinden yararlanabilirripgrepve GNU grep inner literal optimizasyonu yaparripgrep, Rust regex’inregex-syntaxbileşenini kullanarak desen AST’sinden literalleri çıkarır- Rusça sürüm
\w+\s+Холмс\s+\w+için yalnızca Unicode’u düzgün destekleyen araçlar anlamlı sonuç üretebildi - Hiç literal içermeyen uzun
\w{5}\s+...deseninderg, İngilizcede en hızlılar arasındaydı; GNU grep’in Unicode destekli sürümü İngilizcede 90 saniyeden fazla, Rusçada 4 dakikadan fazla sürdüğü için dışarıda bırakıldı ripgrep, UTF-8 çözümlemeyi DFA’ya dahil ederek Unicode desteğini korurken performans da sağlar
Ek benchmark’lar
everything, Linux deposunda.*ile tüm satırları eşleştiren gerçekçi olmayan bir testtirrg, 22.065.361 satırı 1,081 saniyede raporladıagvepttüm satırları raporlamadığından bir eşleşme sınırları var gibi görünüyor
nothing,.*üzerine invert match uygulayıp hiçbir satır raporlamayan bir testtirrg0,302 saniye,git grep0,905 saniye kaydettiptveucginvert search desteklemiyor
context, İngilizce altyazı korpusundaSherlock Holmesçevresindeki 2 satırlık bağlamı yazdırırrg0,612 saniye,sift0,717 saniye ile benzerdiucgbu özelliği desteklemiyor
huge, 9,3 GB’lık İngilizce altyazı bütünündeSherlock Holmesararrg1,786 saniye, GNU grep 5,119 saniye,sift3,047 saniye kaydettiucg, satır sayma koşulunda yalnızca 1.543 satır raporlayarak yanlış sonuç üretti; 2 GB üstü dosya aramasında sorun yaşadığı düşünülüyor
Sonuç
ripgrep, Linux çekirdeği deposu aramalarında tüm benchmark’ları her zaman kazanmadı; ancak performans ve doğruluk açısından başka bir aracın açıkça üstün olduğu da söylenemedigit grep, bazı basit örneklerde birkaç milisaniye öne geçebilse de, desen karmaşıklaştığında veya Unicode gerektiğinderipgrep’in büyük farkla öne geçtiği durumlar olduripgrep’in kod arama performansına şu etkenler katkı sağlıyor- Minimum
statçağrısını hedefleyen hızlı dizin dolaşımı RegexSetkullanarak.gitignoreglob eşleştirmesi- Chase-Lev work stealing queue ile iş dağıtımı
- Çok sayıda küçük dosyada arama yaparken bellek eşlemesi kullanmama tercihi
- Hızlı düzenli ifade motoru
- Minimum
- Tek dosya aramalarında
ripgrep, tüm ana benchmark’larda ya en hızlıydı ya da büyük farkla öndeydi - Tek dosya performansında sparse byte tabanlı
memchr, Teddy SIMD, Aho-Corasick ve UTF-8 çözümlemeyi gömülü yapan DFA etkili olur - Unicode özelliği gerektiren benchmark’larda yalnızca
rg, GNU grep vegit grepanlamlı destek gösterdi; GNU grep vegit grepise genellikle yüksek performans maliyeti ödedi - Bellek eşlemesi, Linux x86_64 ölçütünde çok sayıda küçük dosyanın paralel aranmasında dezavantajlı, tek büyük dosya aramasında avantajlıydı; VM ortamında ek cezası olabilir
1 yorum
Hacker News yorumları
Kesinlikle hızlı ve fzf kombinasyonunu önermeye devam ediyorum
Önce
ripgrepile bulup ardından sonuç dosyası+metin üzerinde fuzzy arama katmanı ekleyen ve bağlamıbatile gösteren bir PowerShell fonksiyonu olarak kullanıyorumBirden fazla deponun karıştığı projelerde, “bir yerde olduğunu biliyorum ama tam konumunu ya da adını bilmiyorsam” çok hızlı şekilde daraltma yapabiliyorum
Bu yöntem https://github.com/junegunn/fzf/blob/master/ADVANCED.md içinden geliyor; hepsini kullanmasanız bile fikir edinmek için göz atmaya değer
fzfentegrasyonunu öneririmYalnızca metin dosyalarında değil, PDF ve zip gibi çeşitli dosya türlerinde de fuzzy arama yapabilirsiniz
Ayrıntılar burada: https://github.com/phiresky/ripgrep-all/wiki/fzf-Integration
rgsonuçlarınıfzfile seçip, seçilen dosya ile satır numarasını parse ederek$EDITOR +"${linenumber}" "$file"ile açıyorElektrikli değirmen yerine kahveyi elle öğütmek gibi
fzfile Git'e eklenecek çok sayıda dosyayı seçip bazılarını atlayabiliyorsunuzgitconfigiçindeki[alias]bölümünefza = "!git ls-files -m -o --exclude-standard | fzf -m --print0 | xargs -0 git add"eklerseniz,git fzaile değiştirilmiş ya da henüz eklenmemiş dosyaların listesi gelir; boşluk tuşuyla öğeleri açıp kapatarak sonraki öğeye geçersinizBu takma ad ve fzf+fd, iş akışımın bazı kısımlarını epey hızlandırıyor
macOS'ta zsh ayarına eklenecekleri derleyen bir rehber de var: https://gist.github.com/aclarknexient/0ffcb98aa262c585c49d4b...
ripgrepi neredeyse aynı şekilde kullanıyorumYüzlerce deponun olduğu bir kod tabanında dosya ya da projeyi daraltmak için bir başlangıç noktası olarak kullanıyor, sonra daha derine iniyorum
Emacs'te
ripgrepi project.el ve dumb-jump paketiyle kullanıyorumEn popüler yöntem olmayabilir ama genel deneyim oldukça tatmin edici
package-installiledumb-jumpkurup sadece(add-hook 'xref-backend-functions #'dumb-jump-xref-activate)ayarını yapmak yeterliPython projelerinde
M-.veyaC-u M-.ile tanımlayıcı tanımını aradığınızda,dumb-jumpmevcut projeye ve dosya türüne görergkomutunu çalıştırıp sonucu Xref buffer'ında gösteriyoragde destekleniyor;agya dargyoksagrepe geri düşüyor, ama home dizininin tamamında ararken beklendiği gibi yavaş olabilirripgrepi oldukça kolay kullanabilirsinizHarici paket şart değil; büyük dizinlerde yavaş
grepyerine kullanmak için(setq xref-search-program 'ripgrep)ayarını yapmanız yeterliBöylece
C-x p g foo RETgibi proje aramaları mevcut projederg -i --null -nH --no-heading --no-messages -g '!*/' -e foobiçiminde çalışırSonuçlar Xref buffer'ında görünür;
n,p,RET,C-ogibi tuşlarla sonraki/önceki eşleşmeye gitmek, kaynağa atlamak ve bölünmüş pencerede göstermek rahattırripgrepin yazarı olarak baktığımda, o regex'i bizzat çalıştırmadım ama --pcre2 bayrağı olmadan da iş görecek gibi duruyorİkinci ve üçüncü
\bassertion'larını da kaldırabilirsiniz; ilki gerekli olabilirripgrepkullandığı veevil-collectionbağları da olduğu için memnuniyetle kullanılabilir: https://github.com/Wilfred/deadgrepBöyle durumlarda normalde
rgrepkullanmış olurdumİlginç olan, VS Code aramasının da artık bir Node.js wrapper üzerinden
ripgrepile çalışıyor olmasıhttps://www.npmjs.com/package/@vscode/ripgrep
ripgrepkuramadığınız bir ortamdaysanız bu harikaVS kurulum yolunun içinde
rgbinary'sini bulabilirsiniz. En azından benim işteki Windows ortamımda mümkündüripgrepi yaklaşık 2 yıldır kullanıyorum ve artık vazgeçilmez bir araç oldugrepten geçmemin ana nedeni kullanım kolaylığıydıVarsayılan olarak
.gitignorekurallarına uyması, gizli dosya/dizinleri ve binary dosyaları atlaması sayesinderg search_term directory, karşılık gelengrepkomutundan çok daha iyi; hız artışı da bonusEşleşme çok uzun olup terminali karmakarışık ettiğinde sık sık
-M 1000gibi -M seçeneğini kullanıyorum-Mgerçekten harikaÖzellikle görmek istemediğiniz minified dosya sonuçlarını yok saymak için çok kullanışlı; ayrıca
-g *.csgibi -g seçeneğiyle yalnızca belirli uzantılardaki dosyalarda arama yapmak da güzelTek başına çalışabilen taşınabilir bir binary olması da faydalı; yeni bir makinede çalışırken çalıştırılabilir dosyayı koyup
greptakma adınırgolarak ayarlarsanız, alışkanlıklagrepyazsanız bile aslındargçalışırBu, 2023'te de hâlâ doğru olabilir; ancak sorun şu ki
ripgrepveyaaggibi paralelleştirilmişgrepalternatifleri klasikgrepten o kadar hızlı ki, aralarındaki küçük hız farklarını ayırt edici ölçüt olarak kullanmak zorlaşıyor.900 bin satırlık bir kod tabanında Emacs içinde
agkullanıyorum ve 16 çekirdekli Ryzen Threadripper 2950X üzerinde neredeyse anında bitiyor.1 saniyenin altını “biraz daha 1 saniyenin altına” indirgeme ihtiyacı hissetmiyorum.
Yeni
greptürü araçların temel niteliği hız değil; farklı açılardan değerlendirilip karşılaştırılmaları gerekiyor.ag'de epey büyük bir performans uçurumu var ve bu blog yazısında da görülebiliyor.Yine de iş yükü kişiden kişiye değiştiği için, bazı durumlarda performans farkı önemli olmayabilir.
900 bin satır çok büyük sayılmaz ve basit sorgular için naif olmayan çoğu
greptürü araç bunu zaten çok hızlı işler.Başka karşılaştırma ölçütlerine bakarsak,
agneredeyse yaşam desteğinde; Debian'dan kaldırılmak üzereyken biri kurtarmış gibi görünüyor: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=999962Blog yazısı Unicode desteğini de karşılaştırıyor ve
ag'nin pratikte Unicode desteği yok. Bu herkes için önemli olmayabilir ama performans dışı bir karşılaştırma ölçütü olarak fazlasıyla yeterli.Arama süresi, dosyaların diskten yüklenme süresi kadar sürüyor ve sonrasındaki farkların anlamlı olması zor.
Dosyalar önbellekteyse, arama süresinden çok dosya sistemi içinde gezinmek ve komutu yazmak baskın hale geliyor; dolayısıyla burada da performans farklarının anlamlı olması güç.
Başlıkta (2016) olması gerekiyor.
Bu, yeni bir bilgi değil; özgün gönderi.
“Ripgrep – A new command line search tool” https://news.ycombinator.com/item?id=12564442 (740 points | Sept 23, 2016 | 209 comments) — hız üzerine tartışma da içeriyor
“Ripgrep is faster (2016)” https://news.ycombinator.com/item?id=17941319 (98 points | Sept 8, 2018 | 40 comments)
qgrep'ten daha hızlı değil.İkisinin çalışma şekli oldukça farklı;
qgrepre2tabanlı olsa da hızını indeksten alıyor.Büyük dosya depolarında her seferinde tüm dosyaları taramak yerine
qgrepve bir indeks kullanmak daha mantıklı; insanların nedenqgrepseçeneğini unuttuğunu merak ediyorum.Ama UTF-8'de çok satırlı eşleşme gerekiyorsa,
ripgrepfarklı bir PCRE2 kütüphanesine geçmek zorunda kaldığından o kadar hızlı olmadığını düşünüyorum.ripgrep'in yazarı olarak,qgrep'in indeksleme kullandığı için indeksleme yapmayan araçlara göre avantajlı olduğu doğru.Bunun karşılığında indeksin kurulması ve korunması gerekiyor; yani UX, “sadece arat” kadar basit değil.
İnsanların
qgrepkullanmamasının sebebi,ripgrepkullanmamalarının “benim için grep zaten yeterince hızlı” gerekçesine benziyor.Küçük arama hedeflerinde çoğu zaman
ripgrepilegrepveyaqgrepileripgreparasındaki hız farkı hissedilmiyor.Eğer
ripgrepLinux çekirdeğinde bir aramayı 100 ms'nin altında bitiriyorsa, standart etkileşimli kullanımda bir indeksleme aracına geçmeye yetecek kadar rahatsızlık olup olmadığı duruma göre değişir, ama çoğu durumda yoktur.ripgrep'e indeksleme ekleme fikrini daha önce düşünmüştüm: https://github.com/BurntSushi/ripgrep/issues/1497Ayrıca çok satırlı arama PCRE2 gerektirmez. Varsayılan regex motoru da Unicode desteklidir ve PCRE2 olmadan derlendiğinde de çok satırlı arama desteği korunur.
ripgrep'ten ugrep'e geçtim ve bir daha geri bakmadım.Hızı benzer ama bulanık eşleştirme var, kod inceleme için işe yarar bir TUI'si var ve PDF ya da sıkıştırılmış dosyaların içinde de arama yapabiliyor.
İsteğe bağlı olarak Google arama sözdizimi kullanılabilmesi de kullanışlı.
https://ugrep.com
ripgrephayranıyım ama yakın zamandaripgrep'te olmayan bir özellik, yani zip arşivlerinin içinde arama, nedeniyleugrep'i keşfettim.Diske çıkarmadan arama yapabiliyorsunuz.
Milyonlarca küçük metin dosyasından oluşan sıkıştırılmış derlemelerle çalışıyorum; hepsini dosya sistemine açmak zorunda kalmamak çok iyi. Bazı dosya sistemleri bu ölçekte zorlanıyor.
Her iki araca da minnettarım; ikisinin de yazarına teşekkürler.
grepiçinde Google arama sözdizimini kullanmaya başlarsam sonuçların çoğunun bir şey satmaya çalışacağından korkuyorum.ugrepveripgrepyazarlarının Reddit'te yıllar boyunca atıştığını düşündüren gönderiler gördüm.Örneğin https://www.reddit.com/r/programming/comments/120wqvr/ripgre...
Sonuçta sadece açık kaynak araçlardan bahsediyoruz ama biraz tuhaf hissettiriyor.
fzf'ye aktarmaktan daha iyi olup olmadığını merak ediyorum.Bana göre
fzf'nin özelleştirilebilirliğini ve esnekliğini geçmek zor görünüyor.Asıl killer feature'ın mevcut grep komut satırı seçenekleriyle uyumluluk gibi görünüyor.
Baştan tamamen yeni bir seçenek kümesi öğrenmek zorunda olmamak oldukça güzel.
Neden
grep'in değiştirilmediği ya da iyileştirilmediği merak ediliyorBu konu da artık biraz eski görünmeye başladı
Atalet, uyumluluk, değişime direnç, yenilikçinin ikilemi gibi şeyler. Bunu olumsuz anlamda söylemiyorum; bunların hepsi benim için de geçerli
Uyumluluk konusunda SSS'ye bakılabilir: https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#pos...
Rahat, etrafınızdaki çalışma ortamına iyi uyuyor ve durduk yere değiştirip her şeyi yeniden ayarlamak için bir neden yok
Benzetme sadece, yakınlarda duran bir Razer sandalyeye kıyafet asılıyor olması noktasına kadar gidiyor
xyzadlı bir program mutlaka bulunmalı, bu argümanı almalı ve tam olarak şöyle davranmalı” gibi tuhaf bir sonuç ortaya çıktıripgrepgibi çeşitli alternatif araçlar kullanılabiliyorEğer amaç
grepkomutunun kendisini başka bir yardımcı programla değiştirmekse, elde edilecek değere kıyasla bozulacak şey çok fazla gibi görünüyorDaha hızlı bir
grepisteyenler başka araçlar kullanır, mevcutgrep'i kullananlar da kullanmaya devam eder; yani zaten ideale yakın bir durum vargrep, her tür dosyada metin arayan genel amaçlı bir araç ve UNIX standardına gömülüBazı programcılar bunu kaynak kod aramak için kullanıyor ama başkaları kaynak kodla ilgisiz metin aramalarında ya da betiklerde kullanıyor ve asla çökmemesini bekliyor
Buna karşılık
ripgrep, esas olarak kaynak kod depolarında arama yapmak için tasarlanmış, uzmanlaşmış ve belirgin tercihleri olan bir araçGenel amaçlı metin aramayı daha da hızlandırmak için çok fazla alan yok.
mmap()kullanılırsa kesilmiş dosyalarda çökme riski olur, düzenli ifade ifade gücü azaltılırsa daha hızlı olabilir ve tüm locale ile karakter seti desteği bırakılıp yalnızca UTF-8/UTF-16 sabitlenebilir ama böyle yapılmamalıPortage'da bakınca PDF ve doc gibi diğer belgeleri de işleyen bir sürüm var gibi görünüyor
https://github.com/phiresky/ripgrep-all