web-dev-qa-db-ja.com

キーの引用符なしのJSON

永続的なメモリヒープをシリアル化するには、合理的にコンパクトでバージョン管理に適した、人間が読めるテキスト形式が必要です。私の Bismon システム(GPLv3)はこのような形式です(テキスト、人間が読める、gitフレンドリー、emacsで編集可能な場合がありますが、Bismonに固有です)。通常は、bismonプログラムによってロードおよびダンプされます。その形式は Bismonテクニカルドラフトレポート (H2020官僚機構の最初の数ページをスキップしてください)、章で文書化されています。§2データとBismonでの永続性 。その形式を使用するファイルの例については、Bismonの store1.bmon (およびその他のstore*.bmonファイル)を調べてください。

私はそのようなフォーマットがJSONのような方がいいかもしれないと考えています(しかし私はわかりません)。多くの開発者がJSONに精通しているからです。

[〜#〜] json [〜#〜] 形式では、オブジェクトキーを引用符で囲んだ文字列にする必要があります。 { "x":1, "y":2 }

私は、JSON表記が非常に役立つ(そして人間が読めるテキストファイル形式が不可欠である)アプリケーション(多分 RefPerSys 、概念的にはBismonになる可能性がある)を考えていますが、キーがalwaysC-identifiers(ラテン文字で始まり、文字、数字、アンダースコアを含む)であるJSONオブジェクトのみを処理します。ただし、そのアプリケーションでは、おそらく100万個のそのようなオブジェクトを解析する必要があり、解析のパフォーマンスは少し重要であり、さらに重要なのはファイル領域が重要である({x:1,y:2}の場合、必要なのは9バイトのみですが、{"x":1,"y":2}には13バイトが必要です(つまり、約40%多いスペース))。私の正確な目標は、テキストで人間が読める形式で、すばやく簡単に機械で解析できるツリー構造のコンパクトなバージョン管理可能な(つまり、gitフレンドリーな)形式です。ほとんどの場合、sameアプリケーションによってダンプおよびロードされます。時々、私はいくつかのエディターでそれをちらりと見たり、そのエディターで少しだけ変更したりする必要があるかもしれません。 jq のような一般的なJSONトランスフォーマーまたはプロセッサーが必要になるとは想像していません。

しかし、私の感覚では、キーがC識別子(および3つのJSONキーワード:truefalsenull)のようなものである場合、引用符を回避できます。たとえば{x:1, y:2}のように。また、一部のJavaScript実装がそれを解析できる可能性があることも理解しています。

特にそのような数百万のJSONオブジェクトを処理する場合、{x:1,y:2}の解析は{ "x":1, "y":2 }または{"x":1,"y":2}の解析よりも速い(単にテキスト表現が少し短いため)と思います。

BismonまたはRefPerSysのようなシステムでは、考えられる例は次のとおりです。

{ oid: _7T9OwSFlgov_0wVJaK1eZbn,
  name: Word,
  mtime: 1502296590.98,
  class: _7T9OwSFlgov_0wVJaK1eZbn,
  attrs: [ { at:  _01h86SAfOfg_1q2oMegGRwW, va: "for words" } ]
}

(現在、Bismonのコミット ff19f15ecd2f647d42 で、同等のものは 1011行目 にあり、store1.bmonの後ろにあります; |はコメントとコメントを区切ります|=Word|のように、解析時にスキップされたため、削除される可能性があります。これらのダンプおよびロードされた*.bmonファイルのコメントは、Bismonが十分に安定すると削除されます)

数年で、私はそのようなJSONオブジェクトを何百万も持つことができました。 bismonプログラムはサーバーであり、毎朝開始され(永続的な状態をテキスト形式でロードし)、毎晩終了します(永続的な状態をテキスト形式でダンプします)。したがって、ロードに1〜2分、ダンプに1〜2分かかると、大きな永続的な状態が許容されます。ただし、そのテキスト永続状態のgit commitedディスクサイズは、より大きな懸念事項です(gitlabgithubの両方が大きなテキストファイルに不満があるため)。

人間が非常にまれにテキスト永続ストアを調べるので(コンパイラの作成者が生成されたアセンブラを調べたり、SQLiteチームが巨大な*.sqlファイル)、読みやすさよりもコンパクトさとgit使いやすさを重視しています。したがって、次のようなコンパクトなものを検討することもできます。

 {oid:_7T9OwSFlgov_0wVJaK1eZbn,nam:Word,mti:1502296590.98,
  cla:_7T9OwSFlgov_0wVJaK1eZbn,
  att:[{a:_01h86SAfOfg_1q2oMegGRwW,v:"for words"}]}

またはsingle行でも同じです。ただし、たまにgit diffができることは価値があります。

言い換えれば、JSONモデルは私にとって非常に素晴らしいものです。しかし、その具体的な構文はそれほどではありません。ほとんどのJSONライブラリにこのような単純化された構文をパッチすることは、おそらく簡単な作業です。

これには3つの質問があります。

  • このようなC識別子キーのみを持つJSON形式のこのような一般的なバリアントの正確な名前は何ですか? ( [〜#〜] yaml [〜#〜] の仕様では、JSONであることが示唆されていますが、厳密にはJSONではなく、それに非常に近いものです)。その形式は厳密にはJSONではありませんが、JSONに非常に似ています(そして、解析ライブラリが存在する場合、正確なJSONへの変換は簡単です)。

  • その形式を扱うオープンソースのCまたはC++ライブラリは何ですか(Linux/x86-64の場合)? JSON解析ライブラリのソースコードをその特殊なケースに適合させるのは簡単なことだと思います。しかし、私は本当に回避したいforking 1つ。

  • 最近のWebブラウザ(FirefoxまたはChrome)は{x:1,y:2}をJSONとして効率的に解析できますか?私はそうと信じがちです(その表記はJavaScriptと完全に互換性があるため)。

この GITおよびYAML の回答が関連する可能性があります。

そして、私はちょうど [〜#〜] hjson [〜#〜] を発見しました。


PS。禁止された名前または予約された名前のリストがあれば、キー内の特定のCキーワードまたは識別子のセットを回避できます。特に、キー名にJavaScriptまたはC++キーワード(forまたはautoまたはwhileなど)を使用することは避けます。私が気にする唯一のプラットフォームはLinux(現在はx86-64)です。

PPS。人間が読めるテキストファイル形式が不可欠な別のアプリケーションは、私の Bismon プロジェクト(GPLv3 +ライセンスに基づく静的ソースコード分析のための永続的な再帰モニター)であり、その理由を Bismonドラフトレポート (H2020ドラフトの成果物であるため、H2020官僚の最初の数ページをスキップしてください)人間が読める独自のテキスト形式を使用するようにBismonで選択しましたが、その特定の選択は大きな間違いだった可能性があり、おそらくこの質問で提案されているように、JSONのようなもの(またはJSON自体)を使用する必要があったでしょう。 RefPerSysプロジェクトは、「Bismon done right」プロジェクトになる可能性があります。また、Bismonの永続データ(たとえば、その store2.bmon テキストファイル)はgit- versionで制御され、ときどき手動で編集されます(ただし、ほとんどの場合、bismon自体によってロードおよびダンプされます)。したがって、はい、テキストデータで20%のスペースの違いが問題になる場合があります。gitlabgithubの両方について、700Kバイトまたは1.1Mバイトのテキストバージョン管理ファイルが表示されます- very違う :Bismonでは、その store2.bmon ファイルはすでにraw形式でのみ表示されています。

JSON辞書のキーは引用符で囲まれた文字列ではなく、文字列です。 JSONの文字列は引用符で始まり、エスケープまたはエスケープされていない文字で続き、文字列で終わります。別のJSONを使用することはできません。別の交換形式を定義することもできますが、それはJSONではなく、完全に独自のものです。

11
gnasher729

データシリアライゼーションフォーマット人間が読める形式 であり、バージョン管理に対応していますが、引用符についてはJSONほど厳密ではありません。

このようなフォーマットは次のとおりです。

  • リラックスしたJSON (RJSON)(単純なキーと単純な値には、通常、引用符は必要ありません)
  • Hjson (通常、単純なキーと単純な値には引用符は必要ありません)
  • [〜#〜] yaml [〜#〜] (通常、キーと値には引用符は必要ありません)
  • JavaScriptオブジェクトリテラル (JavaScriptオブジェクトを渡すと "console.dir()" の多くの実装によっても出力されます。通常、シンプルなキーは引用符で囲む必要はありませんが、文字列値です。一重引用符または二重引用符で囲む必要があります)

完全性のために:

  • [〜#〜] json [〜#〜] (プロパティ名とも呼ばれるキーを二重引用符で囲む必要があり、文字列データ値を二重引用符で囲む必要があります)。
2
David Cary

あなたはファイルシステムを持っています。サブディレクトリに複数のファイルを保存する独自の機能があります。

これは解決します:

  • gitの大きなファイルとバージョン管理では、差分がより明確になり、ファイル自体がはるかに小さくなります。
  • 人間の観察。 gitツリーは変更に対してより高いレベルの通信を提供し、パス構造を持つことで、人間はコンテンツについてより簡単に推論することができます。
  • IO。複数のファイルに分散されていると、並列解析/生成が可能になります。

データ言語についても。基本的なタイプを正確かつ明確に格納でき、マップ、シーケンス、セットなど、データが表現される構造をサポートするものを使用してください。

これはサーバーであり、クライアントにデータを送信しているので、オーバーヘッドを最適化したいのはここだと思います。問題は、ここで正確な使用法を本当に理解する必要があることです。 5Kのメッセージを処理するために50Kのパーサーをダウンロードするのに対し、0Kのパーサー(プラットフォームに組み込まれている)と25Kのメッセージを処理する。最適化は時期尚早かもしれませんが、最適化する場合は、すべての方法でバイナリ形式を実装してください。これは、メッセージの観点からは最も効率的です。また、チャネルベースの圧縮を使用することを忘れないでください。

データがgitに格納されることについてあまり心配する必要はありません。それは独自の圧縮メカニズムを適用します。また、このデータはgitと人間が使いやすい形式である必要があるため、フォーマットはおそらくかなりフォーマットされています。これにより、ファイルサイズの面でオーバーヘッドが増加しますが、Git Deltaと人間の認知負荷は減少します。

リソースが制限されたデバイスで操作しているのでなければ、ディスクへのデータについてあまり心配する必要はありません。その場合、バイナリ形式を使用しないのはなぜですか。

1
Kain0_0