當前位置:
首頁 > 科技 > Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

陶文,技術極簡主義者。認為好的技術是應該是對開發者友好的。一直致力於用技術改進研發效率和開發者體驗。jsoniter [4] 作者,jsoniter 就來自於要不要用 Thrift 替代 JSON 的思考。我認為通過引入 IDL 和高效率的編解碼庫,可以讓 HTTP + JSON 這樣對開發者體驗有好處的技術長久地生存下去。

拿 JSON 襯托 Protobuf 的文章真的太多了,經常可以看到文章中寫道:「快來用 Protobuf 吧,JSON 太慢啦」。但是 Protobuf 真的有那麼牛么?我想從 JSON 切換到 Protobuf 怎麼也得快一倍吧,要不然對不起付出的切換成本?

然而,DSL-JSON 居然聲稱在 Java 語言里, JSON 可以和那些二進位的編解碼格式性能不相上下 [1]!

這太讓人驚訝了!雖然你可能會說,咱們能不用蘋果和梨來做比較了么,兩個東西根本用途完全不一樣,用 Protobuf 是沖著跨語言無歧義的 IDL 的去的,才不僅僅是因為性能!這個我同意,但是仍然有那麼多人盲目相信 Protobuf 一定會快很多,因此我覺得還是有必要通過本文徹底終結一下這個關於速度的傳說。

DSL-JSON 的博客里只給了他們的測試結論,但是沒有給出任何原因,以及優化的細節。這很難讓人信服數據是真實的。你要說 JSON 比二進位格式更快,真的是很反直覺的事情。稍微琢磨一下這個問題,就可以列出好幾個 Protobuf 應該更快的理由:

  • 更容容易綁定值到對象的欄位上。JSON 的欄位是用字元串指定的,相比之下字元串比對應該比基於數字的欄位 tag 更耗時。

  • JSON 是文本的格式,整數和浮點數應該更占空間而且更費時。

  • Protobuf 在正文前有一個大小或者長度的標記,而 JSON 必須全文掃描無法跳過不需要的欄位。

但是僅憑這幾點是不是就可以蓋棺定論了呢?未必,也有相反的觀點:

  • 如果欄位大部分是字元串,佔到決定性因素的因素可能是字元串拷貝的速度,而不是解析的速度。在這個評測 [2] 中,我們看到不少庫的性能是非常接近的。這是因為測試數據中大部分是由字元串構成的。

  • 影響解析速度的決定性因素是分支的數量。因為分支的存在,解析仍然是一個本質上串列的過程。雖然 Protobuf 里沒有 或者 {},但是仍然有類似的分支代碼的存在。如果沒有這些分支的存在,解析不過就是一個 memcpy 的操作而已。只有 Parabix 這樣的技術才有革命性的意義,而 Protobuf 相比 JSON 只是改良而非革命。

  • 也許 Protobuf 是一個理論上更快的格式,但是實現它的庫並不一定就更快。這取決於優化做得好不好,如果有不必要的內存分配或者重複讀取,實際的速度未必就快。

有多個 benchmark 都把 DSL-JSON 列到前三名里,有時甚至比其他的二進位編碼更快。經過我仔細分析,原因出在了這些 benchmark 對於測試數據的構成選擇上。因為構造測試數據很麻煩,所以一般評測只會對相同的測試數據,去測不同的庫的實現。這樣就使得結果是嚴重傾向於某種類型輸入的。比如 [3] 選擇的測試數據的結構是這樣的

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

無論怎麼去構造 small/medium/large 的輸入,benchmark 仍然是存在特定傾向性的。而且這種傾向性是不明確的。比如 medium 的輸入,到底說明了什麼?medium 對於不同的人來說,可能意味著完全不同的東西。所以,在這裡我想改變一下遊戲的規則。不去選擇一個所謂的最現實的配比,而是構造一些極端的情況。這樣,我們可以一目了然的知道,JSON 的強項和弱點都是什麼。通過把這些缺陷放大出來,我們也就可以對最壞的情況有一個清晰的預期。具體在你的場景下性能差距是怎樣的一個區間內,也可以大概預估出來。

好了,廢話不多說了。JMH 擼起來。benchmark 的對象有以下幾個:

  • Jackson:https://github.com/FasterXML/jackson-databindJava 程序里用的最多的 JSON 解析器。benchmark 中開啟了 AfterBurner 的加速特性。

  • DSL-JSON:https://github.com/ngs-doo/dsl-json世界上最快的 Java JSON 實現

  • Jsoniter: http://jsoniter.com/index.cn.html我抄襲 DSL-JSON 寫的實現。特別申明:我是 Jsoniter 的作者。這裡提到的所有關於Jsoniter 的評測數據都不應該被盲目相信。大部分的性能優化技巧是從 DSL-JSON 中直接抄來的。

  • Fastjson:https://github.com/alibaba/fastjson在中國很流行的 JSON 解析器

  • Protobuf:https://github.com/google/protobuf在 RPC (遠程方法調用)里非常流行的二進位編解碼格式

  • Thrift:https://thrift.apache.org另外一個很流行的 RPC 編解碼格式。這裡 benchmark 的是 TCompactProtocol

先從一個簡單的場景入手。毫無疑問,Protobuf 非常擅長於處理整數


相比 Jackson ns/op
Protobuf 8.20 22124.431
Thrift 6.6 27232.761
Jsoniter 6.45 28131.009
DSL-JSON 4.48 40472.032
Fastjson 2.1 86555.965
Jackson 1 181357.349

從結果上看,似乎優勢非常明顯。但是因為只有 1 個整數欄位,所以可能整數解析的成本沒有佔到大頭。所以,我們把測試調整對象調整為 10 個整數欄位。再比比看

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話


相比 Jackson ns/op
Protobuf 8.51 71067.990
Thrift 2.98 202921.616
Jsoniter 3.22 187654.012
DSL-JSON 1.43 422839.151
Fastjson 1.4 432494.654
Jackson 1 604894.752

這下優勢就非常明顯了。毫無疑問,Protobuf 解析整數的速度是非常快的,能夠達到 Jackson 的 8 倍

DSL-JSON 比 Jackson 快很多,它的優化代碼在這裡

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

整數是直接從輸入的位元組里計算出來的,公式是 value = (value << 3) + (value << 1) + ind; 相比讀出字元串,然後調用 Integer.valueOf ,這個實現只遍歷了一遍輸入,同時也避免了內存分配。

Jsoniter在這個基礎上做了循環展開

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

編碼方面情況如何呢?和編碼一樣的測試數據,測試結果如下:


相比 Jackson ns/op
Protobuf 2.9 121027.285
Thrift 0.17 2128221.323
Jsoniter 2.02 173912.732
DSL-JSON 2.18 161038.645
Fastjson 0.81 431348.853
Jackson 1 351430.048

不知道為啥,Thrift 的序列化特別慢。而且別的 benchmark 里 Thrift 的序列化都是算慢的。我猜測應該是實現里有不夠優化的地方吧,格式應該沒問題。整數編碼方面,Protobuf 是 Jackson 的 3 倍。但是和 DSL-JSON 比起來,好像沒有快很多。

這是因為 DSL-JSON 使用了自己的優化方式,和 JDK 的官方實現不一樣

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

這段代碼的意思是比較令人費解的。不知道哪裡就做了數字到字元串的轉換了。過程是這樣的,假設輸入了19823,會被分解為 19 和 823 兩部分。然後有一個 `DIGITS` 的查找表,根據這個表把 19 翻譯為 "19",把 823 翻譯為 "823"。其中 "823" 並不是三個byte分開來存的,而是把 bit 放到了一個integer里,然後在 writeBuf 的時候通過位移把對應的三個byte解開的

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

這個實現比 JDK 自帶的 Integer.toString 更快。因為查找表預先計算好了,節省了運行時的計算成本。

解析 JSON 的 Double 就更慢了。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話


相比 Jackson ns/op
Protobuf 13.75 92447.958
Thrift 7.30 174052.307
Jsoniter 4.2 302453.323
Jsoniter (base64) 3.25 390812.895
DSL-JSON 2.53 502287.602
Fastjson 1.2 1055454.855
Jackson 1 1271311.735

Protobuf 解析 double 是 Jackson 的 13 倍。毫無疑問,JSON 真的不適合存浮點數。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

浮點數被去掉了點,存成了 long 類型,然後再除以對應的 10 的倍數。如果輸入是 3.1415,則會變成 31415/10000。

把 double 編碼為文本格式就更困難了。


相比 Jackson ns/op
Protobuf 12.71 143346.157
Thrift 0.87 2093533.015
Jsoniter (6 digits) 6.5 280252.226
Jsoniter (base64) 6.68 272843.205
DSL-JSON 1.23 1483965.621
Fastjson 1.06 1722392.219
Jackson 1 1822478.053

解碼 double 的時候,Protobuf 是 Jackson 的 13 倍。如果你願意犧牲精度的話,Jsoniter可以選擇只保留 6 位小數。在這個取捨下,可以好一些,但是 Protobuf 仍然是Jsoniter的兩倍。

保留 6 位小數的代碼是這樣寫的。把 double 的處理變成了長整數的處理。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

到目前來看,我們可以說 JSON 不是為數字設計的。如果你使用的是 Jackson,切換到 Protobuf 的話可以把數字的處理速度提高 10 倍。然而 DSL-Json 做的優化可以把這個性能差距大幅縮小,解碼在 3x ~ 4x 之間,編碼在 1.3x ~ 2x 之間(前提是犧牲 double 的編碼精度)。

因為 JSON 處理 double 非常慢。所以 Jsoniter提供了一種把 double 的 IEEE 754 的二進位表示(64個bit)用 base64 編碼之後保存的方案。如果希望提高速度,但是又要保持精度,可以使用 Base64FloatSupport.enableEncodersAndDecoders;

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

對於 0.123456789 就變成了 "OWNfmt03P78"

我們已經看到了 JSON 在處理數字方面的笨拙醜態了。在處理對象綁定方面,是不是也一樣不堪?前面的 benchmark 結果那麼差和按欄位做綁定是不是有關係?畢竟我們有 10 個欄位要處理那。這就來看看在處理欄位方面的效率問題。

為了讓比較起來公平一些,我們使用很短的 ascii 編碼的字元串作為欄位的值。這樣字元串拷貝的成本大家都差不到哪裡去。所以性能上要有差距,必然是和按欄位綁定值有關係。


相比 Jackson ns/op
Protobuf 2.52 68666.658
Thrift 2.74 63139.324
Jsoniter 5.78 29887.361
DSL-JSON 5.32 32458.030
Fastjson 1.71 101107.721
Jackson 1 172747.146

如果只有一個欄位,Protobuf 是 Jackson 的 2.5 倍。但是比 DSL-JSON 要慢。

我們再把同樣的實驗重複幾次,分別對應 5 個欄位,10個欄位的情況。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話


相比 Jackson ns/op
Protobuf 1.3 276972.857
Thrift 1.44 250016.572
Jsoniter 2.5 143807.401
DSL-JSON 2.41 149261.728
Fastjson 1.39 259296.397
Jackson 1 359868.351

在有 5 個欄位的情況下,Protobuf 僅僅是 Jackson 的 1.3x 倍。如果你認為 JSON 對象綁定很慢,而且會決定 JSON 解析的整體性能。對不起,你錯了。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話


相比 Jackson ns/op
Protobuf 1.22 462167.920
Thrift 1.12 503725.605
Jsoniter 2.04 277531.128
DSL-JSON 1.84 307569.103
Fastjson 1.18 477492.445
Jackson 1 564942.726

把欄位數量加到了 10 個之後,Protobuf 僅僅是 Jackson 的 1.22 倍了。看到這裡,你應該懂了吧。

Protobuf 在處理欄位綁定的時候,用的是 switch case:

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

這個實現比 Hashmap 來說,僅僅是稍微略快而已。DSL-JSON 的實現是先 hash,然後也是類似的分發的方式:

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

使用的 hash 演算法是 FNV-1a。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

是 hash 就會碰撞,所以用起來需要小心。如果輸入很有可能包含未知的欄位,則需要放棄速度選擇匹配之後再查一下欄位是不是嚴格相等的。Jsoniter有一個解碼模式

DYNAMIC_MODE_AND_MATCH_FIELD_STRICTLY,它可以產生下面這樣的嚴格匹配的代碼:

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

即便是嚴格匹配,速度上也是有保證的。DSL-JSON 也有選項,可以在 hash 匹配之後額外加一次字元串 equals 檢查。


相比 Jackson ns/op
Jsoniter (hash mode) 2.13 274949.346
Jsoniter (strict mode) 1.95 300524.989
DSL-JSON (hash mode) 1.91 305812.208
DSL-JSON (strict mode) 1.71 343203.344
Jackson 1 585421.314

關於對象綁定來說,只要欄位名不長,基於數字的 tag 分發並不會比 JSON 具有明顯優勢,即便是相比最慢的 Jackson 來說也是如此。

廢話不多說了,直接比較一下三種欄位數量情況下,編碼的速度

只有 1 個欄位


相比 Jackson ns/op
Protobuf 1.22 57502.775
Thrift 0.86 137094.627
Jsoniter 2.06 57081.756
DSL-JSON 2.46 47890.664
Fastjson 0.92 127421.715
Jackson 1 117604.479

有 5 個欄位


相比 Jackson ns/op
Protobuf 1.68 127933.179
Thrift 0.46 467818.566
Jsoniter 2.54 84702.001
DSL-JSON 2.68 80211.517
Fastjson 0.98 219373.346
Jackson 1 214802.686

有 10 個欄位


相比 Jackson ns/op
Protobuf 1.72 194371.476
Thrift 0.38 888230.783
Jsoniter 2.59 129305.086
DSL-JSON 2.56 130379.967
Fastjson 1.06 315267.365
Jackson 1 334297.953

對象編碼方面,Protobuf 是 Jackson 的 1.7 倍。但是速度其實比 DSL-Json 還要慢。

優化對象編碼的方式是,一次性儘可能多的把控制類的位元組寫出去。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

可以看到我們把 "field1": 作為一個整體寫出去了。如果我們知道欄位是非空的,則可以進一步的把字元串的雙引號也一起合并寫出去。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

從對象的編解碼的 benchmark 結果可以看出,Protobuf 在這個方面僅僅比 Jackson 略微強一些,而比 DSL-Json 要慢。

Protobuf 對於整數列表有特別的支持,可以打包存儲

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

設置 [packed=true]


相比 Jackson ns/op
Protobuf 2.92 249888.105
Thrift 3.63 201439.691
Jsoniter 2.97 245837.298
DSL-JSON 1.97 370897.998
Fastjson 0.89 820099.921
Jackson 1 730450.607

對於整數列表的解碼,Protobuf 是 Jackson 的 3 倍。然而比 DSL-Json 的優勢並不明顯。

在 Jsoniter里,解碼的循環被展開了:

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

對於成員比較少的情況,這樣搞可以避免數組的擴容帶來的內存拷貝。

Protobuf 在編碼數組的時候應該有優勢,不用寫那麼多逗號出來嘛。


相比 Jackson ns/op
Protobuf 1.35 159337.360
Thrift 0.45 472555.572
Jsoniter 1.9 112770.811
DSL-JSON 2.19 97998.250
Fastjson 0.66 323194.122
Jackson 1 214409.223

Protobuf 在編碼整數列表的時候,僅僅是 Jackson 的 1.35 倍。雖然 Protobuf 在處理對象的整數欄位的時候優勢明顯,但是在處理整數的列表時卻不是如此。在這個方面,DSL-Json 沒有特殊的優化,性能的提高純粹只是因為單個數字的編碼速度提高了。

列表經常用做對象的容器。測試這種兩種容器組合嵌套的場景,也很有代表意義。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話


相比 Jackson ns/op
Protobuf 1.26 1118704.310
Thrift 1.3 1078278.555
Jsoniter 2.91 483304.365
DSL-JSON 2.22 635179.183
Fastjson 1.12 1260390.104
Jackson 1 1407116.476

Protobuf 處理對象列表是 Jackson 的 1.3 倍。但是不及 DSL-JSON。


相比 Jackson ns/op
Protobuf 2.22 328219.768
Thrift 0.38 1885052.964
Jsoniter 3.63 200420.923
DSL-JSON 3.87 187964.594
Fastjson 0.85 857771.520
Jackson 1 727582.950

Protobuf 處理對象列表的編碼速度是 Jackson 的 2 倍。但是 DSL-JSON 仍然比 Protobuf 更快。似乎 Protobuf 在處理列表的編碼解碼方面優勢不明顯。

Java 的數組有點特殊,double 是比 List 更高效的。使用 double 數組來代表時間點上的值或者坐標是非常常見的做法。然而,Protobuf 的 Java 庫沒有提供 double 的支持,repeated 總是使用 List。我們可以預期 JSON 庫在這裡有一定的優勢。


相比 Jackson ns/op
Protobuf 5.18 207503.316
Thrift 6.12 175678.703
Jsoniter 4.83 222818.772
Jsoniter (base64) 3.63 296262.142
DSL-JSON 2.8 383549.289
Fastjson 0.58 1866460.535
Jackson 1 1075423.265

Protobuf 在處理 double 數組方面,Jackson 與之的差距被縮小為 5 倍。Protobuf 與 DSL-JSON 相比,優勢已經不明顯了。所以如果你有很多的 double 數值需要處理,這些數值必須是在對象的欄位上,才會引起性能的巨大差別,對於數組裡的 double,優勢差距被縮小。

在 Jsoniter里,處理數組的循環也是被展開的。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

這避免了數組擴容的開銷。

再來看看 double 數組的編碼


相比 Jackson ns/op
Protobuf 15.63 107760.788
Thrift 0.54 3125678.472
Jsoniter (6 digits) 6.74 249945.866
Jsoniter (base64) 7.11 236991.658
DSL-JSON 1.14 1478332.248
Fastjson 1.08 1562377.465
Jackson 1 1684935.837

Protobuf 可以飛快地對 double 數組進行編碼,是 Jackson 的 15 倍。在犧牲精度的情況下,Protobuf 只是Jsoniter的 2.3 倍。所以,再次證明了,JSON 處理 double 非常慢。如果用 base64 編碼 double,則可以保持精度,速度和犧牲精度時一樣。

JSON 字元串包含了轉義字元的支持。Protobuf 解碼字元串僅僅是一個內存拷貝。理應更快才對。被測試的字元串長度是 160 個位元組的 ascii。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話


相比 Jackson ns/op
Protobuf 1.85 173680.548
Thrift 2.29 140635.170
Jsoniter 2.4 134067.924
DSL-JSON 2.27 141419.108
Fastjson 1.14 281061.212
Jackson 1 321406.155

Protobuf 解碼長字元串是 Jackson 的 1.85 倍。然而,DSL-Json 比 Protobuf 更快。這就有點奇怪了,JSON 的處理負擔更重,為什麼會更快呢?

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

這個捷徑里規避了處理轉義字元和utf8字元串的成本。

在 JDK9 之前,java.lang.String 都是基於 `char` 的。而輸入都是 byte 並且是 utf-8 編碼的。所以這使得,我們不能直接用 memcpy 的方式來處理字元串的解碼問題。

但是在 JDK9 里,java.lang.String 已經改成了基於`byte`的了。從 JDK9 的源代碼里可以看出:

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

使用這個雖然被廢棄,但是還沒有被刪除的構造函數,我們可以使用 Arrays.copyOfRange 來直接構造 java.lang.String 了。然而,在測試之後,發現這個實現方式並沒有比 DSL-JSON 的實現更快。

似乎 JVM 的 Hotspot 動態編譯時對這段循環的代碼做了模式匹配,識別出了更高效的實現方式。即便是在 JDK9 使用 +UseCompactStrings 的前提下,理論上來說本應該更慢的 byte => char => byte 並沒有使得這段代碼變慢,DSL-JSON 的實現還是最快的。

如果輸入大部分是字元串,這個優化就變得至關重要了。Java 里的解析藝術,還不如說是位元組拷貝的藝術。JVM 的 java.lang.String 設計實在是太愚蠢了。在現代一點的語言中,比如 Go,字元串都是基於 utf-8 byte 的。

類似的問題,因為需要把 char 轉換為 byte,所以沒法直接內存拷貝。


相比 Jackson ns/op
Protobuf 0.96 262077.921
Thrift 0.99 252140.935
Jsoniter 1.5 166381.978
DSL-JSON 1.38 181008.120
Fastjson 0.74 339919.707
Jackson 1 250431.354

Protobuf 在編碼長字元串時,比 Jackson 略微快一點點。一切都歸咎於 char。

JSON 是一個沒有 header 的格式。因為沒有 header,JSON 需要掃描每個位元組才可以定位到所需的欄位上。中間可能要掃過很多不需要處理的欄位。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

消息用 PbTestWriteObject 來編碼,然後用 PbTestReadObject 來解碼。field1 和 field2 的內容應該被跳過。


相比 Jackson ns/op
Protobuf 5.05 152194.483
Thrift 5.43 141467.209
Jsoniter 3.75 204704.100
DSL-JSON 2.51 305784.845
Fastjson 0.4 1949277.734
Jackson 1 768840.597

Protobuf 在跳過數據結構方面,是 Jackson 的 5 倍。但是如果跳過長的字元串,JSON 的成本是和字元串長度線性相關的,而 Protobuf 則是一個常量操作。

最後,我們把所有的戰果匯總到一起。


場景 Protobuf V.S. Jackson Protobuf V.S. Jsoniter Jsoniter V.S Jackson
Decode Integer 8.51 2.64 3.22
Encode Integer 2.9 1.44 2.02
Decode Double 13.75 3.27 4.2
Encode Double 12.71 1.96 (只保留小數點後6位) 6.5
Decode Object 1.22 0.6 2.04
Encode Object 1.72 0.67 2.59
Decode Integer List 2.92 0.98 2.97
Encode Integer List 1.35 0.71 1.9
Decode Object List 1.26 0.43 2.91
Encode Object List 2.22 0.61 3.63
Decode Double Array 5.18 1.47 4.83
Encode Double Array 15.63 2.32 (只保留小數點後6位) 6.74
Decode String 1.85 0.77 2.4
Encode String 0.96 0.63 1.5
Skip Structure 5.05 1.35 3.75

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

編解碼數字的時候,JSON 仍然是非常慢的。Jsoniter把這個差距從 10 倍縮小到了 3 倍多一些。

JSON 最差的情況是下面幾種:

  • 跳過非常長的字元串:和字元串長度線性相關。

  • 解碼 double 欄位:Protobuf 優勢明顯,是 Jsoniter 的 3.27 倍,是 Jackson 的 13.75 倍。

  • 編碼 double 欄位:如果不能接受只保留 6 位小數,Protobuf 是 Jackson 的 12.71 倍。如果接受精度損失,Protobuf 是 Jsoniter 的 1.96 倍。

  • 解碼整數:Protobuf 是 Jsoniter 的 2.64 倍,是 Jackson 的 8.51 倍。

Protobuf有沒有比JSON快5倍?用代碼來擊破pb性能神話

如果你的生產環境中的 JSON 沒有那麼多的 double 欄位,都是字元串佔大頭,那麼基本上來說替換成 Protobuf 也就是僅僅比 Jsoniter提高一點點,肯定在 2 倍之內。如果不幸的話,沒準 Protobuf 還要更慢一點。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 高可用架構 的精彩文章:

模塊化還是微服務-為什麼說大部分團隊微服務化都走入了陷阱

TAG:高可用架構 |

您可能感興趣

Surface Book2有了15英寸新版本,性能比Surface Studio還要強!
蘋果A11性能有多強?力壓Intel i7版MacBook Pro
蘋果A10X Fusion處理器性有多強?GPU性能秒了Core i7集顯!
ROG Zephyrus:顏值性能甩了Macbook幾條街
Xbox One X性能強大 與PS4 Pro有「天壤之別」
這 3個JS 性能基礎,讓 Bluebird 更快速
蘋果A11跑分出爐,性能跟Macbook Pro有一拼
iPhone X性能超iPad Pro,但Macbook Pro也被秒?
微軟全新Surface Pro亮相 性能是iPad Pro的1.7倍
Galaxy S8和iPhone7 Plus——三大性能比拼
不止是高性能,Project Scorpio將支持FreeSync 2、HDMI 2.1
三大性能比拼——Galaxy S8和iPhone7 Plus對決
Xbox天蠍座性能比PS4 Pro強 但沒啥用
iPhone 8 Plus性能碾壓7 Plus!不服跑個分
AMD Forrest Norrod:耗時5年打造EPYC 性能與性價比兼備
微軟Xbox市場部總經理Aaron Greenberg訪談:Xbox One X性能強勁且極具性價比
Android手機用戶要哭!性能被iPhone 8超出逾50%
iPhone 8 Plus的性能還不如iPhone7 Plus?
iPhone 7 Plus/Galaxy S8相機性能半斤八兩