世界を動かす技術を、日本語で。

Jqのより高速な代替手段

概要

  • jsongrep はJSONドキュメントのパス検索に特化した高速ツール
  • DFA(決定性有限オートマトン) ベースの検索エンジンを採用し、O(1)でパス探索を実現
  • クエリ構文 は正規表現的で、シンプルかつ直感的
  • ベンチマーク で他のツール(jq等)と比較し、高速性を証明
  • Rust製クロスプラットフォーム ツールとして、今後の発展が期待される

jsongrep導入と特徴

  • jsongrep はJSONドキュメントのパスにマッチする値を抽出する検索ツール
  • Rust製 で、クロスプラットフォーム対応(バイナリ配布あり)
  • インストールcargo install jsongrepで簡単
  • クエリ言語 はパス指定、ワイルドカード、オルタネーション(|)、再帰、オプション(?)など正規表現的な記法
  • パイプ対応--with-pathオプションで出力制御が可能

クエリ例

  • ドット区切りでネストしたフィールド指定:
    • roommates[0].name
  • ワイルドカードで全要素対象:
    • favorite_drinks[*]
  • オルタネーションで複数候補:
    • name | roommates
  • 再帰的探索:
    • (* | [*])*.name
    • -F name(ショートカット)
  • オプション(存在しなくてもOK):
    • roommates[0].favorite_food?

jsongrepの強みと弱み

  • 強み

    • JSONドキュメントを 木構造 としてパス探索
    • クエリを DFA にコンパイルし、探索時は1回の状態遷移のみ
    • O(1) で各エッジを処理、バックトラックや再帰的探索不要
    • jqjmespath 等のツールよりも検索に特化し圧倒的高速
  • 弱み

    • jq ほど普及していない
    • クエリ言語は 変換・加工 には非対応(検索専用)
    • フィルタ・演算・文字列補間 等は不可
    • 新しいツールで、実運用での実績は少ない

jsongrepのDFAベース検索エンジン

  • 検索エンジンのパイプライン
    • JSONドキュメントを 木構造 にパース(serde_json_borrow利用)
    • クエリ文字列を AST にパース(pestライブラリ)
    • ASTから NFA (非決定性有限オートマトン)をGlushkov法で構築
    • NFAを DFA に変換(subset construction)
    • JSON木をDFAで辿り、マッチする値を収集

クエリASTの例と構文

  • 構文要素
    • フィールド名、配列インデックス、範囲、ワイルドカード、オプション(?)、Kleeneスター(*)、オルタネーション(|)、シーケンス(.)
  • :
    • roommates[*].name → Sequence構造のAST

JSON木構造

  • オブジェクトのキーや配列インデックスが エッジ、値が ノード
  • クエリは ルートから葉までのパス 集合を定義

Glushkov法によるNFA構築

  • クエリを 直線化 し、各シンボルにユニークな位置番号を付与
  • First/Last/Followsセット を計算し、状態遷移を決定
  • ε遷移なし のNFAを生成し、後のDFA化を容易に

NFAからDFAへの変換

  • subset construction (パワーセット構成法)でNFAの状態集合をDFAの1状態にマッピング
  • DFAは常に1状態のみを保持し、 O(1) の遷移で探索を実現

ベンチマーク戦略と結果

  • 比較対象: jq, jmespath, jsonpath-rust等
  • 評価指標: パース時間、クエリコンパイル時間、検索時間、エンドツーエンド時間
  • データセット: xlarge(約190MB)等、実用規模のJSON
  • 結果: jsongrepは検索速度で他ツールを大きく上回る

まとめ・参考情報

  • jsongrep は検索特化で設計された、 高速・シンプル なJSONパス探索ツール
  • 正規表現的クエリ言語DFAエンジン により、圧倒的なパフォーマンスを実現
  • jq 等の変換・加工ツールとは用途が異なるため、使い分けが重要

参考リンク

Hackerたちの意見

ページを最初に開いたとき、ライトモードで色が崩れてた。もし同じ問題に遭遇した人がいたら、ダークモードに切り替えてからライトモードに戻すと直るよ。

Edge/Windowsでは問題ないよ。

同じ問題があったよ(Braveブラウザ)。

明るい背景に白い文字、うん。

AndroidのFirefoxでは問題なし。ただ、グラフのスケールがバラバラで比較しづらいのが難点。比較なしのグラフもたくさんあるから、数字の意味がわからない…

iOSのSafariでも壊れてるよ。

このウェブサイトは、ツール自体と同じように「バイブコード」されてる気がする。

これ、もう修正されたと思う。CSSでダークモードの一部がライトモードに漏れてたみたい。

最近のプログラマーはユーザー体験に気を使ってるよね。リーダーモードで読み込む方がいいよ。

新しいCLIツールの中で、スピードが売りのものが多いけど、正直言ってjqみたいなツールが遅いと感じたことはないな。みんなどうやって過ごしてるの?既存のツールじゃ物足りないってこと?それとも「新しいターミナルが107ms早く開くけど、気づかないけど、なんか気分がいい」みたいな感じ?

TBサイズのndjsonファイルを処理してるんだけど、jqを使って処理パイプラインの段階間で簡単な変換(例えばフィールド名を変更する)をしたいんだけど、遅すぎて使い物にならないから、結局一回限りのNodeやRustのスクリプトを書くことにしてる。

スピードって、実はそれ自体が一つの価値なんだよね。遅いものにイライラしてるから、他の選択肢を探すことをつい忘れがち。でも、たまにすごく最適化されたツールやページが現れて、即座にフィードバックがもらえると、本当に使うのが楽しくなる。そういうのに敏感な人とそうでない人がいると思う。必見のリンクね https://m.xkcd.com/1205

何かが遅いって気づくのは、そのスピードが目立つ使い方に出会ったときだけだよね。そうすると、全体的に遅さが見えてくる。コマンドが完了していないことに気づいて、それについて考えをまとめられるなら、それは遅い(頭の中より遅いから、つまり遅い!)。普通、敏感なユーザーや技術者は、ツールの限界に合わせて使い方を調整できるけど、もし制限のないツールが見つかれば、それはすごく優れたものに感じるよね。例えば、ripgrepが私のワークフローに浸透していない唯一の場所はパイプの後なんだけど、それはただの(悪い?)習慣から来てる。だから、時々無駄に「rg "" | grep」ってやっちゃって、その後に心の中で顔を手で覆うことになる。jgが「jg | jq」で私を変えてくれるか見てみよう :)

最適化 = 良いこと。SEOの速度を同じ機能や構文のサポートより優先すること(特にその欠点をすぐに目立たせない場合)は、マーケティングのウソだね。jqより速いけど、jqができることはできない…必要な時にプレフィルターとして使えるかも。

主に本当に大きなログファイルを扱ってるよ。ハイパースケーラーで働いてると、サービスのログ量は異常なレベルになって、ログ周りのツールはたくさんあるけど、数テラバイトをローカルに引っ張ってきてじっくり見るのが一番の代替手段だと思う。

簡単なループだね: - 誰かがツールXを好きになる - コードの代替案を考える - パフォーマンスのためにRustか、お気に入りの言語を選ぶ - Claudeが小さな機能のサブセットを実装する - ベンチマークする - 勝利を主張して、ショーケースで利益を得る 注意:この特定のプロジェクトには目立った兆候があまりないけど、過剰なドキュメント化のパターン(17%のコメント対コード比、READMEに1000語以上、Claude風のコメントパターン)があるから、ガイド付きのプロセスかもしれない。やっぱりこのプロジェクトは「サブセットはセットより速い」ってトレンドに従ってると思う。

50GBのログを処理したり、JSONをcronジョブでパイプする人たちにとって、2倍のスピードアップは壁の時間やクラウドの請求書に影響が出るから、ただのターミナル脳のナンセンスじゃないよ。ほとんどの人は気にしないだろうね。jqを手動で数回実行するだけなら、「速いjq」ってのは速いトースターと同じくらい魅力的じゃない。こういうツールがまだ注目されるのは、スピードが簡単にアピールできるからだし、あるチームがCIやデータパイプラインで一つの厄介なボトルネックにぶつかって、古いツールがもう受け入れられないって判断したからなんだ。

ripgrepとugrepのレースは面白いよね。

ダッシュボードやアラート用にJSONレスポンスをパースしてるよ。ノードが何千もあって、モニタリングの解像度によってはここで改善が見込めるかも。

jqの使い方は、ターミナルでインタラクティブに使う人だけじゃないからね、信じられないかもしれないけど。

いくつかのデータ処理CLIツール、例えばjq、mlr、htmlq、xsv、yqなどを学んだよ。アドベントオブコードを完走するレベルではないけど、日常的には十分使える。データを抽出するためのフォーマットや異なる構文が多すぎて、終わりがなかったんだけど、nushellを見つけてからは全部これに置き換わった。一つの構文で全部できるから、すごく新鮮な感じ!

私も同じ!nushellは最高だよ!他のシェルでやってたよりも、ずっと多くのことを自動化できるようになった。構文が直感的で一貫性があって、bashでif文やループを書くのをいつも忘れてた私には本当に助かる ^^

同じく!Nushellにほとんど置き換えられたよ。補完を設定するのにちょっと手間がかかったし、コマンドの発見性に小さな粗さがあったけど、前のoh-my-zshのセットアップよりはずっと良いよ。理想を言えば、ユーザーに型注釈を書かせるフラグや、スクリプトを静的バイナリとしてコンパイルする機能、TUIライブラリもあったら、ちょっと小さなアプリを書くのに真剣に考えるけど、今の状態でも好きだし感謝してる。

jqyqを使ったことがあるけど、後者のパフォーマンスについて文句を言ったことは一度もないよ。後者は前者よりも何倍も遅いのにね。だから、もしjqより速いものがあるなら、そのツールの作者はすごいと思うけど、広い意味ではそのパフォーマンスの利点は特定のニッチなユーザー層に必要とされるんじゃないかな。JSON形式のログを分析する人たちとか?でも、改行区切りのJSONがそのシナリオでは最強だから、速いjqの意味が薄れてしまう。とはいえ、いつも速いソフトウェアが好きで、最適化オタクの私としては、脱帽だね!

サーバーソフトウェアと統合する場合、パフォーマンスは大事だよね。例えば、jqのようなロジックが必要なリクエストが10万RPS来ることもあるし。CLIツールについては、君が言ったように、どれも大体のケースではパフォーマンスは問題ないよ。

jqyqを使ったことがあるけど、もしよければ、どのyqを使ってるの?Go版とPythonのパススルー版があって、後者にはxqやtomlqも含まれてるよ。

そうなんだ、みんなが君みたいにこれらのツールを使ってるわけじゃないってことがわかったよ。変だね!

まずは、おめでとう!素晴らしいツールだね!次に、プレゼンテーションについてのコメントだけど、横向きのバイオリングラフはいいけど、全てのツールが同じ色だから、jsongrepがどこにあるのか見つけるのが難しい。ツールごとにグループ分けして色分けすることをおすすめするよ。それに、jq自体はグラフに全く入ってない(でも、投稿のタイトルを見て入ってると思った!)。最後に、xLargeは190MiBのファイルなんだね。驚いたよ。xLargeにしては少なすぎる気がする。私は毎日400MiBのJSONドキュメントをチェックしてるし、時にはGiBのものもあるから。

パフォーマンスは大事だと思うけど、ns/us/msで物事を測るためのこの終わらない戦いは、ちょっとパフォーマティブに感じるな。確かに、0.000001%のエッジケースではそれが次の大きなボトルネックになるかもしれないけど。フロントエンドのツールでも同じことが繰り返されてるよね。みんな自分たちの方がずっと速いって主張してる。今使ってるツールの9割は全然問題ないと思うよ。例えば、私は本当に大きなファイルでgrepをよく使うけど、rgに切り替えるのはほんの数回だけだね。

確かに、エージェントツールはOpencodeやClaudeCodeなどからかなり恩恵を受けることができるよね。遅いと感じるし、何かを速くすることができればそれは勝ちだよね :)

それはあなたにとってのほんの数回のケースだね。重要な時は本当に重要だよ。

フロントエンドのツールでも同じことが繰り返されてるのを見かけるよね。みんな自分たちの方が ずっと 速いって主張してる。 > > 今使ってるツールの9割は全然問題ないよ。フロントエンドで働いてるの? 複雑なウェブアプリで? だとしたら、これは完全に間違ってると思う。パフォーマンスの問題は、フロントエンドチームの一番の不満だよ。コンパイルやテスト、(少しはアプリ自体も)でね。

それな。ツールがjqと差別化できる主な方法は、もっと直感的な構文と、構文を見せるための実世界の例がたくさんあることだと思う。

こういう開発に対する印象があるときは、私の2セントを考えてみて:ただ「私はターゲットオーディエンスじゃない」と思えばいい。それでいいんだ。2msと0.2msの違いは、あなたには不要に思えるかもしれないし、バカみたいに感じるかもしれない。でも、どこかでTBサイズのJSONオブジェクトをストリーム処理してる人がいて、その人たちは気にするだろう。これらのニュースは彼らのためのものだよ。

別の視点から見てみるのもいいかも。より良いパフォーマンス == 無駄なCPUサイクルが少ないってこと。どれだけの人が毎日jqを使ってるか考えてみて、速い実装によってどれだけのエネルギーが節約できるかを考えてみよう。エネルギーがますます貴重になっている今、こういうことを考えるべきだよね。

その気持ちはわかるけど、みんなそう思ってるから、結局は「千の紙切れで死ぬ」ってことになるんだよね。「個人なんて重要じゃない、自分の貢献なんてちっぽけだ」っていうのと同じ感覚。社会は個人の集まりだから、みんなが自分の役割を果たさないとね。

9/10、今使ってるツールは全然問題ないよ。 でも、実際はそうじゃない。ソフトウェアはハードウェアが速くなるよりも早く遅くなってる。40年前のコンピュータよりも3〜4桁以上速いものがあるのに、なんだか全てが遅くなってるよね。

そうだね、jqが遅すぎたってケースは一度も覚えてないな。今本当に欲しいのは、もっと直感的で理解しやすいjqだね。

これらの例でjqの同等の式があれば、表現力を比較するのに役立つかもしれないし、jqが(サブ)クエリがDFAを許す時に「ただ」使えるかどうかも見えるかもしれない。grepやripgrepなどはクエリに基づいてアルゴリズムを変えるから、スピード向上が自動的に実現されるんだよね。

しばらく前に性能よりも「正確さ」のためにJaq[0]に切り替えたんだけど、Jaqもjqよりパフォーマンスが良いって主張してるよ。 [0]: https://github.com/01mf02/jaq

ベンチマークのデータビジュアライゼーションがかなり雑だと思う。再構築して、色や形を使って追加の次元を引き出せば、もっと効果的になると思うよ。誰も生のファイルパスをラベルとしてスキャンして、結果が何なのかを理解しようとは思わないからね。

Jqの構文はめっちゃ難しくて、いつも覚えられないから、シンプルなJSONから値を取る方法を調べる必要があるんだよね。

jqを使うのが本当に嫌いなんだ。AIに頼る数少ないものの一つだよ。