En Hızlı Düzenli İfade (Regular Expression) Aracı Hangisi?

3
FZ

Metin verisi işlemek ve aramak söz konusu olduğunda, düzenli ifadeler (regular expressions) ve bunları kullanmamızı sağlayan yazılımlar en sık başvurduğumuz şeylerden biridir. Yazılımla uğraşan, komut satırında bir şeyler yapan kişilerin grep ya da benzeri bir araç kullanmadan yaşadıklarını düşünmek imkansızdır.

Bu yazdıklarımda herhangi bir yenilik yok elbette. Ben de doğal olarak onlarca yıldır severek kullanılan ve çok fayda sağlayan düzenli ifade teknolojisinde pek bir yenilik olmadığını düşünüyordum kısa bir süre öncesine dek. Ama yanılmışım!

Bu yazıda son zamanlarda hayatımıza giren iki yeni düzenli ifade aracından çok kısaca bahsedeceğim: ICgrep and ripgrep.

ICGrep, Kanada'daki Simon Fraser üniversitesinde Dr. Robert D. Cameron tarafından geliştirilen yeni ve paralel 'bitstream' teknolojisine dayanan bir düzenli ifade ve metin işleme aracı. Bu alanda pek çok kullanim şekli için en hızlı sistem olma iddiasını taşıyor. ICGrep'in MacOS / OS X icin calıstırılabilir halini http://www.icgrep.com/downloads.htm adresinden temin etmek mümkun. Diger isletim sistemleri için ise yine açık olarak erisilebilen kaynak kodundan kendiniz derleyebilirsiniz.

ripgrep ise Andrew Gallant ve diger yazılımcılar tarafindan Rust programlama dili kullanılarak GitHub uzerinden geliştirilen bir düzenli ifade aracı; kaynak kodu için adres: https://github.com/BurntSushi/ripgrep. Tıpkı ICGrep gibi, ripgrep de cok hızlı olma, tam Unicode destegi gibi özellikler sunduğunu belirtiyor. Buna ek olarak 'Silver Searcher (ag)' ve 'ack' gibi özellikleri bulunduğunu, yani özellikle Git ile calisan yazılımcıların kaynak kod dosyalarında bir şeyler ararken işleri kolaylastırdığını belirtmekte de fayda var.

Hiçbir bilimsellik iddiasi gütmeyen bu performans kıyaslamasında kullandıgım bilgisayarda icgrep, ripgrep, işletim sistemi ile birlikte kurulu gelen BSD grep, GNU grep ve agyi (Silver Searcher) kıyaslayacağım çok basitce.

Test ettigim ortamın özellikleri: OS X El Capitain Version 10.11.4, 2.8 GHz Intel Core i7, 16 GB 1600 MHz DDR3 RAM, ve 500 GB SSD.

Kullandıgım metin dosyası su adresten indirdiğim Arapça Wikipedia sayfaları (hepsini içeren tek bir dosya): https://dumps.wikimedia.org/arwiki/latest/arwiki-latest-pages-articles.xml.bz2 (tarih: 01-Oct-2016 19:56. Büyüklük: 510,252,224 byte (sıkıstırılmıs halde); 3,311,291,975 byte (açık halde) yani yaklasık 3.1 GB). Her düzenli ifade komutunu 5 kere çalıştırıp ortalamaları not ettim.

Önce OS X ile gelen BSD grep ile başlayalım:

$ /usr/bin/grep --version
grep (BSD grep) 2.5.1-FreeBSD

$ time /usr/bin/grep -c -i Wats.n arwiki-latest-pages-articles.xml
793

real   1m6.120s
user   1m5.550s
sys    0m0.530s

Elbette bu çok basit bir düzenli ifade ama unutmayın ki içinde arama yaptığımız metin dosyasının büyüklügü 3.1 GB. Bu işlem yaklasik 1 dakika sürdü. Elbette çok daha iyi bir performans saglamak mümkün.

GNU grepi deneyelim:

$ /usr/local/bin/grep --version
grep (GNU grep) 2.26

$ time /usr/local/bin/grep -c -i Wats.n arwiki-latest-pages-articles.xml
793

real    0m2.628s
user    0m2.168s
sys     0m0.457s

1 dakikadan 2 saniyeye indik. Hiç fena sayılmaz. Ama günlük olarak genellikle ag kullanıyorum, o yüzden bir de onun performansına bakalım:

$ ag --version
ag version 0.31.0

Features:
+jit +lzma +zlib

$ time ag -c -i Wats.n arwiki-latest-pages-articles.xml
ERR: Skipping arwiki-latest-pages-articles.xml: pcre_exec() can't handle files larger than 2147483647 bytes.

Görünen o ki, en azından agnin bu sürümü GBlar mertebesindeki metin dosyalarını işleyemiyor. Simdi sıra geldi yeni araçları denemeye:

icgrep ile başlayalım ve aynı şeyi deneyelim:

$ icgrep --version
LLVM (http://llvm.org/):
LLVM version 3.5.0svn
Optimized build.
Built Nov  4 2015 (10:54:34).
Default target: x86_64-apple-darwin15.4.0
Host CPU: core-avx2

$ time icgrep -c -i Wats.n arwiki-latest-pages-articles.xml
793

real    0m3.022s
user    0m2.028s
sys     0m0.993s

Gördügümüz gibi icgrep nerede ise GNU grep kadar hızlı bu basit düzenli ifade işlemi için.

Aynı seyi ripgrep ile deneyelim:

$ rg --version
0.2.6

$ time rg -c -i Wats.n arwiki-latest-pages-articles.xml
793

real    0m4.340s
user    0m3.780s
sys     0m0.560s

Bu durumda ripgrep, icgrep ve GNU grepe kıyasla biraz daha yavaş görünüyor.

Bu düzenli ifade programlarının performansına dair çok kaba saba da olsa bir fikrimiz oluştuğuna göre, biraz daha ilginç ve Unicode ile ilgili bir düzenli ifade denemesi yapabiliriz: 3.1 GB Arapça metin içinde acaba hiç Yunan harfi geciyor mu, geçiyorsa kaç tane?

OS X ile gelen BSD grep Unicode ifadelerini desteklemediği icin onu kıyaslama dışında bırakıyoruz. agnin de 3.1 GB büyüklüğünde dosya ile basa çıkamadığını yukarıda görmüştük. Dolayısı ile geriye sadece GNU grep, icgrep, ve ripgrep kalıyor:

$ time /usr/local/bin/grep -P -c '\p{Greek}' arwiki-latest-pages-articles.xml
14480

real    0m27.130s
user    0m26.580s
sys     0m0.510s

Yukarıdaki sorguya gore GNU grep ile 3.1 GB'lik dosya içinde geçen 14.430 tane Yunan harfinin varlığını tespit etmek 27 saniye sürdü.

Daha iyisini yapabilir miyiz? icgrep ile deneyelim:

$ time icgrep -c '\p{Greek}' arwiki-latest-pages-articles.xml
14480

real    0m3.203s
user    0m2.168s
sys     0m1.034s

Üniversitedeki araştırma geliştirme çabasının icgrep üzerindeki olumlu etkisi burada kendini gösteriyor: yaklasık 3 saniyede aynı işlemi tamamlayabildik.

Peki ama ripgrep aynı aramayi ne kadar sürede yapabilecek?

$ time rg -c '\p{Greek}' arwiki-latest-pages-articles.xml
14480

real    0m6.800s
user    0m6.230s
sys     0m0.540s

Görünen o ki, bu tür düzenli ifade aramalarinda, ripgrep, icpgrepten yaklaşık 2 kat daha yavaş ama yine de GNU grepe kıyasla çok daha hızlı.

O halde bu maçın galibi kim? Bu basit soruya basit bir cevap vermek mümkün degil. Cevap biraz da sizin durumunuza baglı. ICgrep yoğun bir araştırma geliştirme çabasının ürünü, akademik ortamdan çıkan, yepyeni teknikler kullanan bir araç. Lakin kolayca kurup denemek istiyorsanız bu sadece MacOS / OS X ortamında mümkün. Eger kaynak kodu indirip GNU/Linux ortaminda derleyip kullanmaya çalısacaksanız kolay gelsin.

Diger yandan, ripgrep de epey hızlı ve akıllıca davraniyor. MacOS, GNU/Linux ve MS Windows için kolayca kurabileceginiz çalıştırılabilir dosyaları sundugu için hemen kullanmaya başlayabilirsiniz. Benim açımdan 'Silver Searcher' yani ag komutunun yerine geçmeye aday.

ICgrep'in gelistiricisi ile ripgrep'in gelistiricisi arasindaki ilginç bir tartışmayı ve değişik performans kıyaslamalarını su adresten takip edebilirsiniz: https://news.ycombinator.com/item?id=12586928. Ayrıca https://github.com/BurntSushi/ripgrep/issues/63 adresinde de benzer konular ele alinmis ripgrep geliştiricisi tarafından.

Düzenli ifadelerle ilgili daha bilimsel ve detaylı bir performans kıyaslaması için http://sljit.sourceforge.net/regex_perf.html adresini ziyaret edebilirsiniz ama bu calisma henüz ICgrep ve ripgrep'e dair kıyaslamaları içermiyor.

Kaynak: Faster, RegEx! Match! Match! (Which Regular Expression Utility is the Fastest?)

Görüşler

0
hb

Kucuk bir not: bu araclari benchmark ederken, OS'in disk cache'ini temizlemek daha tutarli sonuclar verebilir.

0
FZ

Dogru diyorsun. Hem biraz üsengeclikten hem de diskten okuma vb. seyleri dahil etmek istemeyip hafizada bulunan dosya uzerinden CPU'yu ne kadar etkin kullanabileceklerini merak ettigimden daha gercekci bir kiyaslama yapmamis oldum. Lakin bu yorum uzerine bu sefer usenmeyip cok kisaca bakayim dedim, basit ve Unicode kiyaslamalar icin. Her seferinde sudo purge calistirip biraz bekleyip öyle deneme yaptim ve birkac kez calistirip ortalamalarini aldim, yaklasik olarak cikan manzara asagidaki gibi:

Basit düzenli ifade örnegi icin performans:

ripgrep real 0m5.372s user 0m4.149s sys 0m0.999s

icgrep real 0m8.900s user 0m1.990s sys 0m1.580s

GNU grep: real 0m3.310s user 0m2.290s sys 0m0.760s

Unicode örnegi icin performans:

icgrep real 0m8.830s user 0m2.010s sys 0m1.580s

ripgrep: real 0m8.080s user 0m7.050s sys 0m1.130s

GNU grep: real 0m28.020s user 0m27.020s sys 0m0.920s

Bu sonuclara bakarak (ve suradaki keyifli yazismalari da okuduktan sonra) vardigim sonuc benzer: ripgrepe bir sans vermeyi düsünüyorum, agnin tahtina oturabilir belki benim kullanim senaryolarim acisindan. ICgrep ise, gun gelir de GNU/Linux icin kolayca kurulabilir hale gelirse ve bazi spesifik durumlarda daha yuksek performans gerektiren bir seylerle karsilasirsam tekrar dönüp bakacagim bir araç olacak.

Görüş belirtmek için giriş yapın...