17 puan yazan GN⁺ 2026-03-28 | 3 yorum | WhatsApp'ta paylaş
  • JSON belgelerinde yol tabanlı gezinme yapan bir Rust CLI aracı ve mevcut jq, jmespath, jsonpath-rust, jql araçlarından arama hızı daha yüksek
  • Sorguları düzenli dil olarak ifade edip DFA'ya derliyor ve JSON ağacını tek geçişte dolaşan yapısıyla O(n) sürede işliyor
  • zero-copy parsing destekleyen serde_json_borrow kullanarak bellek ayırmayı en aza indiriyor ve ripgrep'in performans felsefesinden ilham alarak tasarlanmış
  • Benchmark sonuçlarına göre büyük JSON'larda bile uçtan uca performansı en iyi ve arama odaklı basit bir sorgu dili sunuyor
  • MIT lisansı ile yayımlanmış; DFA tabanlı sorgu motoru bir Rust kütüphanesi olarak yeniden kullanılabiliyor

jsongrep'e genel bakış

  • jsongrep, JSON belgelerinde yol tabanlı değer aramak için kullanılan Rust tabanlı bir CLI aracı ve jq, jmespath, jsonpath-rust, jql'den daha hızlı olmayı hedefliyor
  • JSON belgesini bir ağaç olarak ele alıyor; yol (path) ifadelerini düzenli dil (regular language) olarak tanımlayıp DFA'ya (Deterministic Finite Automaton) derledikten sonra tek geçişte arama yapıyor
  • Sorgu dili basit ve arama odaklı tasarlanmış; dönüştürme veya hesaplama özellikleri yok
  • serde_json_borrow ile zero-copy parsing yaparak bellek ayırmayı en aza indiriyor
  • Geliştirilirken ripgrep'in tasarım felsefesi ve performans yaklaşımı örnek alınmış

jsongrep kullanım örnekleri

  • jg komutu sorgu ve JSON girdisi alır; yolu sorguyla eşleşen tüm değerleri çıktılar
  • Nokta gösterimi (dot path) ile iç içe alanlara erişim
    • jg 'roommates[0].name'"Alice"
  • Wildcard (*, [*]) ile tüm anahtarları veya indeksleri eşleştirme
  • Alternation (|) ile birden fazla yol arasından birini seçme
  • Özyinelemeli arama ((* | [*])*) ile herhangi bir derinlikte alan arama
  • Optional (?) ile 0 veya 1 kez eşleşme desteği
  • -F seçeneğiyle belirli alan adlarını hızlıca arama
  • Pipe (| less, | sort) kullanıldığında yol çıktısını otomatik olarak gizler; --with-path ile zorla gösterilebilir

jsongrep'in temel kavramları

  • JSON bir ağaç yapısıdır; nesne anahtarları ve dizi indeksleri kenar (edge) görevi görür
  • Sorgu, kökten belirli bir düğüme kadar olan yol kümelerini tanımlar
  • Sorgu dili düzenli dil olarak tasarlandığı için DFA'ya dönüştürülebilir
  • DFA girdiyi yalnızca bir kez okur ve backtracking olmadan O(n) sürede arama yapar
  • Mevcut araçlar (jq, jmespath vb.) sorguları yorumlayarak özyinelemeli biçimde arama yaparken, jsongrep önceden derlenmiş DFA ile tek geçişte arama yapar

DFA tabanlı sorgu motorunun yapısı

  • İş hattı 5 aşamadan oluşur
    1. serde_json_borrow ile JSON'u ağaç olarak parse etme
    2. Sorguyu AST'ye parse etme
    3. Glushkov algoritmasıyla NFA oluşturma
    4. Subset Construction ile DFA'ya dönüştürme
    5. DFA geçişlerini izleyerek JSON ağacını tek DFS ile dolaşma
  • Sorgu parse etme

    • PEG grameri (pest kütüphanesi kullanılıyor) ile sorguyu Query AST'sine dönüştürür
    • Başlıca sözdizimi öğeleri: Field, Index, Range, FieldWildcard, ArrayWildcard, Optional, KleeneStar, Disjunction, Sequence
    • Örnek: roommates[*].nameSequence(Field("roommates"), ArrayWildcard, Field("name"))
  • JSON ağaç modeli

    • Nesne anahtarları ve dizi indeksleri kenar, değerler ise düğümdür
    • Örneğin roommates[*].name, roommates[0]name yolunu dolaşır
  • NFA oluşturma (Glushkov algoritması)

    • ε-geçişi olmayan bir NFA oluşturur
    • Aşamalar
      1. Sorgu sembollerine konum numarası verme
      2. First/Last/Follows kümelerini hesaplama
      3. Her konum arasındaki geçişleri kurma
    • Örnek sorgu roommates[*].name için NFA, 4 durumdan oluşan basit doğrusal bir yapıdır
  • DFA'ya dönüştürme (Subset Construction)

    • NFA durum kümeleri temel alınarak deterministik bir DFA oluşturulur
    • Her durum, bir NFA durum kümesine karşılık gelir
    • Gereksiz anahtarları verimli biçimde atlamak için Other sembolü eklenir
    • Basit sorgular NFA ile aynı yapıya sahip bir DFA'ya dönüşür
  • DFS tabanlı arama

    • Kökten başlayıp her kenar boyunca DFA geçişi yapılır
    • Geçiş yoksa ilgili alt ağaç budanır (prune)
    • DFA durumu accepting ise yol ve değer kaydedilir
    • Her düğüm en fazla bir kez ziyaret edilir; toplam arama O(n) olur
    • serde_json_borrow sayesinde dizeler kopyalanmadan özgün buffer referans alınır

Benchmark metodolojisi

  • Criterion.rs ile istatistik tabanlı benchmark yapıldı
  • Veri kümeleri

    • simple.json (106B), kubernetes-definitions.json (~992KB), kestra-0.19.0.json (~7.6MB), citylots.json (~190MB)
  • Karşılaştırılan araçlar

    • jsongrep, jsonpath-rust, jmespath, jaq, jql
  • Benchmark grupları

    1. document_parse: JSON parse hızı
    2. query_compile: sorgu derleme süresi
    3. query_search: yalnızca arama
    4. end_to_end: tüm iş hattı
  • Adalet için dikkate alınanlar

    • zero-copy parsing avantajı ayrı ölçüldü
    • DFA derleme maliyeti ayrı ölçüldü
    • Özelliği olmayan araçlar ilgili testlerden çıkarıldı
    • Veri kopyalama maliyeti ayrı ele alındı

Benchmark sonuçları

  • Belge parse süresi: serde_json_borrow en hızlısı
  • Sorgu derleme süresi: jsongrep, DFA oluşturduğu için en yüksek maliyete sahip; jmespath çok daha hızlı
  • Arama süresi: jsongrep, tüm araçlar arasında en hızlısı
  • Uçtan uca performans: 190MB veri kümesinde bile jq, jmespath, jsonpath-rust, jql'den ezici biçimde daha hızlı
  • Tüm sonuçlar canlı benchmark sitesinde görülebilir

Lisans ve kullanım

  • MIT lisanslı açık kaynak yazılım
  • GitHub, Crates.io ve Docs.rs üzerinden kullanılabilir
  • DFA tabanlı sorgu motoru kütüphane olarak yeniden kullanılabilir ve Rust projelerine doğrudan entegre edilebilir

Kaynakça

  • Glushkov, V. M. (1961), The Abstract Theory of Automata
  • Rabin, M. O., & Scott, D. (1959), Finite Automata and Their Decision Problems

3 yorum

 
roxie 26 일 전

Harika görünüyor.

 
lamanus 2026-03-28

| Dikey çizgi neden gövde metninde farklı görünüyor? İlginçmiş..

 
GN⁺ 2026-03-28
Hacker News görüşleri
  • jq'nun sözdizimi fazla anlaşılmaz olduğu için, her seferinde basit bir JSON değeri bile almak istesem aratmam gerekiyor

    • İlginç. Ben jq sözdizimini sezgisel buluyorum; shell pipeline gibi nokta, pipe ve köşeli parantez kullanmaya alışığım
      Genelde tek seferlik filtreler yazdığım için, okumaktan çok yazmaya zaman harcıyorum
      Muhtemelen kullanım senaryom basit ya da jq düşünme biçimime iyi uyuyor
      Tüm CLI araçlarının JSON girdi/çıktısı verip jq ile birbirine bağlandığı bir dünya hayal ediyorum ama bu sizin için kâbus gibi olurdu
    • jq sık kullanmadığım için “öğrenme vadisinde” kalan bir araç
      Her kullandığımda yeniden öğrenmem gerektiğinden sezgisel gelmiyor
      sed de Turing-complete olmasına rağmen çoğu kişi onu en fazla regex değiştirme için kullanıyor
    • Yaptığım celq aracını öneririm
      jq'yu seviyorum ama geçmişte kendi yazdığım sorguları bile anlayamadığım oldu
      celq, daha tanıdık olan CEL dilini kullanıyor
    • Ben de benzer nedenle dq adlı bir araç yaptım
      Bu araç basitçe JavaScript ile JSON işliyor ve şaşırtıcı biçimde jq'dan daha hızlı
      $ cat package.json | dq 'Object.keys(data).slice(0, 5)' gibi kullanılıyor
    • JSON'un kendisi zaten çok fazla gereksiz sözdizimsel gürültü içerdiği için can sıkıcı
      Clojure öğrendiğim için artık JSON yerine EDN kullanıyorum
      Daha kısa, daha okunabilir ve yapısal olarak işlenmesi daha kolay
      Son zamanlarda verileri borkdude/jet ya da babashka ile işliyor, djblue/portal ile görselleştiriyorum
      jq'nun o karmaşık operatörlerinde neden ısrar edildiğini anlayamıyorum
  • Performansı önemsiyorum ama nanosaniye düzeyindeki karşılaştırmalar bana gösteriş amaçlı performans gibi geliyor
    Çoğu durumda şu an kullandığımız araç yeterli
    Örneğin ben sadece büyük dosyalarda grep yerine rg kullanıyorum

    • Böyle düşünüyorsanız “ben hedef kullanıcı değilim” diye düşünebilirsiniz
      2 ms ile 0.2 ms arasındaki fark önemsiz görünebilir ama TB ölçeğinde akış işleyen biri için önemlidir
    • Ama herkes böyle düşünürse sonunda küçük verimsizlikler birikir ve her şey yavaşlar
      Donanım hızlandı ama yazılımın tersine yavaşladığı bir gerçeklikte yaşıyoruz
    • jq'nun öne çıkması için sezgisel bir sözdizimi ve gerçek kullanım örnekleri daha fazla olmalı
    • “Yeterince hızlı” sözü beni hep rahatsız eder
      Optimizasyondan kaçınmak bana tembellik ve hayal gücü eksikliği gibi geliyor
      Ağ gecikmesinden hızlı diye rahatlamak kulağa bahane gibi geliyor
    • Ben de hızdan çok kullanılabilirlik ve özellikleri daha önemli görüyorum
      JSON fazla büyükse JSON yerine ikili bir format kullanmak gerekir
      CLI'da karmaşık pipeline'lar kurmak gerekiyorsa, bence doğrudan program yazmak daha iyi
  • Pek çok yeni CLI aracı “daha hızlı” olduğunu öne sürüyor ama gerçekte jq'nun yavaş olduğunu neredeyse hiç hissetmedim

    • Ben TB ölçeğinde ndjson dosyalarıyla çalışıyorum
      jq ile sadece alan adlarını değiştiren basit işler bile fazla yavaş olduğu için işi doğrudan Node veya Rust scriptleriyle yapıyorum
    • Çok büyük log dosyaları ile uğraşıyorsanız jq yavaş hissedilebilir
      Hyperscaler ortamlarında birkaç TB log doğrudan indirilip analiz ediliyor
    • Biz binlerce düğümden gelen JSON yanıtlarını parse ediyoruz
      İzleme çözünürlüğüne göre performans farkı hissedilebilir
    • Her yeni araç çıktığında aynı “Rust ile yeniden yapılmış daha hızlı sürüm” kalıbı tekrarlanıyor
      Özelliklerin sadece bir kısmı uygulanıyor ve benchmark ile zafer ilan ediliyor
      Bu proje de o “alt küme daha hızlıdır” eğiliminin bir parçası gibi görünüyor
    • Bir aracın yavaş olduğunu ancak gerçekten yavaşladığı anda fark ediyorsunuz
      Ondan sonra her şey yavaş gelmeye başlıyor
      ripgrep gibi hızlı bir aracı bir kez kullandıktan sonra geri dönmek zor oluyor
  • Hem jq hem yq kullandım ama yq çok daha yavaş olmasına rağmen bundan hiç şikâyet etmedim
    jq'dan daha hızlı bir araç varsa güzel ama buna sadece belirli bir kullanıcı kitlesi ihtiyaç duyar
    Yine de optimizasyonu seven biri olarak saygı duyuyorum

    • Hangi yq'dan söz ettiğinizi merak ettim — Go sürümü mü, Python sürümü mü?
    • Sunucu entegrasyon ortamlarında performans önemli ama CLI'da çoğu zaman yeterince hızlı
    • ArcGIS'ten dışa aktarılan birkaç GB GeoJSON verisini jq ile işliyorum
      ETL aşamasında epey zaman alıyor
    • Herkes araçları aynı şekilde kullanmıyor
  • Sayfayı ilk açtığımda light mode renkleri bozuktu
    Dark mode'a geçip geri dönünce düzeldi

    • Site de araç gibi biraz vibe-coded yapılmış hissi veriyor
    • Ben yazarıyım; light mode kullanmadığım için test etmeyi atlamışım, hemen düzelteceğim
    • Sorun, CSS'te dark mode stillerinin kısmen sızmasıydı
    • Android Firefox'ta iyiydi ama grafik ölçekleri birbirinden farklıydı, bu yüzden karşılaştırmak zordu
    • Şimdi düzeltildi
  • Ben doğruluk nedeniyle Jaq'a geçtim
    Performansının da jq'dan iyi olduğu söyleniyor

    • Öneri için teşekkürler. jaq, jsongrep'e kıyasla daha doğru yöne evrilmiş gibi görünüyor
    • Yalnız jaq 3.0, dağıtımlardaki jq paketinden hızlı olsa da elle derlenmiş jq daha hızlı
      jq'nun yavaş olduğuna dair ün, dağıtım paketleme sorunlarından kaynaklanıyor gibi görünüyor
  • İşim gereği sık sık newline-delimited JSON (jsonl) ile uğraşıyorum
    Her satır tam bir JSON nesnesi; başlıca CLI araçlarının bu formatı destekleyip desteklemediğini merak ediyorum

  • jq, mlr, htmlq, xsv, yq gibi çeşitli veri işleme CLI araçları kullandım ama
    Nushell'i keşfettikten sonra hepsinin yerini o aldı
    Tüm formatları tek bir sözdizimiyle işleyebilmek çok ferahlatıcıydı

    • Ben de 2023'ün ortasından beri Nushell'i ana shell'im olarak kullanıyorum
      Yalnız ekip arkadaşlarıyla çalışırken jq, yq, mlr kullanmaya devam ediyorum
    • Ben de çoğunu Nushell ile değiştirdim
      Otomatik tamamlama ayarı ve komutların keşfedilebilirliği konusunda biraz rahatsızlık var ama oh-my-zsh'den çok daha iyi
      Zorunlu type annotation, statik binary derleme ve bir TUI kütüphanesi de gelirse küçük uygulamalar yazmak için bile kullanırım
    • Katılıyorum. Nushell, sezgisel ve tutarlı sözdizimi sayesinde otomasyonu çok daha kolaylaştırıyor
  • Harika bir araç! Yalnız benchmark görselleştirmesi biraz zayıf kalmış
    Tüm araçlar aynı renkte olduğu için jsongrep'in nerede olduğunu bulmak zor
    jq da grafikte yoktu, bu da kafa karıştırıcıydı
    xLarge dosyası 190 MiB ile küçük sayılır; ben sık sık 400 MiB ile 1 GiB arası JSON işliyorum

    • Ben yazarı olarak yanıtlayayım. Mevcut benchmark aralığı yaklaşık 106 B ile 190 MB arasında
      Daha büyük herkese açık JSON belgeleri varsa paylaşmanız iyi olur
  • Benchmark görselleştirmesi kaba hissettiriyor
    Renk ya da şekil kullanarak daha fazla boyut ifade edilebilirdi
    Sonuçları anlamak için dosya yollarını tek tek okumak zorunda kalmak kullanışsız