高速Json(逆)シーケンス化オープンソースプロジェクトJilを共有
17397 ワード
JSONのシーケンス化ライブラリは欠けていませんが、非常にパフォーマンスの良いライブラリが欠けています.これはウェブサイトにとって非常に重要です.今日はJilを見つけました.
彼はオープンソースのコードです:https://github.com/kevin-montrose/Jil
彼のホームページにはその性能の表現が詳しく紹介されていますが、私はここで転記しません.彼の最も重要な特徴は性能です.Emitはもちろん少なくありません.他のライブラリの光を超えさせたいなら、Emitはきっとだめです.彼は他にも多くの最適化があります.共通バッファ GCのプレッシャーを紹介するためにbuilder.CommonCharBufferのような機能バッファ、builder.CommonStringBufferもこのような応用です.インライン 多くの方法では、コンパイラが可能な限りインラインするように[MethodImplOperations.AggressiveInlining)]とマークされています.減少計算 例えばintをstringに変換し、元のコードはこのように書かれています.
もういいと思っているのではないでしょうか.しかし、彼らは絶えず進取して、このようにしました.
その中で、あのDigitPairsは何ですか?
考えが高いのではないでしょうか.
減少判定 もとの方法はこうだった
このように変えることができて、はは、実は私はこのように変えたいです.ほとんどの場合空白ではないと思うので、4回判断してから戻るのですが、私はこのように変更しました.
彼はオープンソースのコードです:https://github.com/kevin-montrose/Jil
彼のホームページにはその性能の表現が詳しく紹介されていますが、私はここで転記しません.彼の最も重要な特徴は性能です.Emitはもちろん少なくありません.他のライブラリの光を超えさせたいなら、Emitはきっとだめです.彼は他にも多くの最適化があります.
1 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2 static void _CustomWriteInt(TextWriter writer, int number, char[] buffer)
3 {
4 // Gotta special case this, we can't negate it
5 if (number == int.MinValue)
6 {
7 writer.Write("-2147483648");
8 return;
9 }
10
11 var ptr = InlineSerializer<object>.CharBufferSize - 1;
12
13 var copy = number;
14 if (copy < 0)
15 {
16 copy = -copy;
17 }
18
19 do
20 {
21 var ix = copy % 10;
22 copy /= 10;
23
24 buffer[ptr] = (char)('0' + ix);
25 ptr--;
26 } while (copy != 0);
27
28 if (number < 0)
29 {
30 buffer[ptr] = '-';
31 ptr--;
32 }
33
34 writer.Write(buffer, ptr + 1, InlineSerializer<object>.CharBufferSize - 1 - ptr);
35 }
もういいと思っているのではないでしょうか.しかし、彼らは絶えず進取して、このようにしました.
1 [MethodImpl(MethodImplOptions.AggressiveInlining)]
2 static void _CustomWriteInt(TextWriter writer, int number, char[] buffer)
3 {
4 var ptr = InlineSerializer<object>.CharBufferSize - 1;
5
6 uint copy;
7 if (number >= 0)
8 copy = (uint)number;
9 else
10 {
11 writer.Write('-');
12 copy = 1 + (uint)~number;
13 }
14
15 do
16 {
17 var ix = copy % 100;
18 copy /= 100;
19
20 var chars = DigitPairs[ix];
21 buffer[ptr--] = chars.Second;
22 buffer[ptr--] = chars.First;
23 } while (copy != 0);
24
25 if (buffer[ptr + 1] == '0')
26 ++ptr;
27
28 writer.Write(buffer, ptr + 1, InlineSerializer<object>.CharBufferSize - 1 - ptr);
29 }
その中で、あのDigitPairsは何ですか?
1 struct TwoDigits
2 {
3 public readonly char First;
4 public readonly char Second;
5
6 public TwoDigits(char first, char second)
7 {
8 First = first;
9 Second = second;
10 }
11 }
12
13 private static readonly TwoDigits[] DigitPairs;
14
15 static Methods()
16 {
17 DigitPairs = new TwoDigits[100];
18 for (var i=0; i < 100; ++i)
19 DigitPairs[i] = new TwoDigits((char)('0' + (i / 10)), (char)+('0' + (i % 10)));
20 }
考えが高いのではないでしょうか.
1 static bool IsWhiteSpace(int c)
2 {
3 // per http://www.ietf.org/rfc/rfc4627.txt
4 // insignificant whitespace in JSON is defined as
5 // \u0020 - space
6 // \u0009 - tab
7 // \u000A - new line
8 // \u000D - carriage return
9
10 return
11 c == 0x20 ||
12 c == 0x09 ||
13 c == 0x0A ||
14 c == 0x0D;
15 }
このように変えることができて、はは、実は私はこのように変えたいです.ほとんどの場合空白ではないと思うので、4回判断してから戻るのですが、私はこのように変更しました.
1 static bool IsWhiteSpace(int c)
2 {
3 // per http://www.ietf.org/rfc/rfc4627.txt
4 // insignificant whitespace in JSON is defined as
5 // \u0020 - space
6 // \u0009 - tab
7 // \u000A - new line
8 // \u000D - carriage return
9
10 return
11 c < 0x21 && (
12 c == 0x20 ||
13 c == 0x09 ||
14 c == 0x0A ||
15 c == 0x0D);
16 }