【问题标题】:Golang: Parsing benchmarking between message pack and JSONGolang:消息包和 JSON 之间的解析基准测试
【发布时间】:2013-12-07 19:33:30
【问题描述】:

我们正在开发一个 TCP 服务器,它通过 TCP 接收简单的基于文本的命令(类似于 redis)

我们在使用原始文本命令、JSON 或消息包 (http://msgpack.org/) 之间折腾

一个命令的例子可以是:

文本命令:LOCK some_random_key 1000

JSON 命令:{"command":"LOCK","key":"some_random_key","timeout":1000}

消息包:\x83\xA7command\xA4LOCK\xA3key\xAFsome_random_key\xA7timeout\xCD\x03\xE8

问题:

编辑:我想出了我自己的问题,即解析 JSON 和 MsgPack 之间的速度比较。请在我的回答中查看结果

【问题讨论】:

  • 您的问题并没有说明什么更重要,数据流大小或可读性,您是否正在加密(SSL 或其他任何方式)数据流(他们通常在加密之前压缩数据)等。我建议考虑“用户”而不是“服务器”,记住如果有人需要读取你的 JSON 数据,他需要它是可读的,如果它的机器与机器通信,压缩

标签: json go messagepack


【解决方案1】:

解析速度对比:

BenchmarkJSON     100000         17888 ns/op
BenchmarkMsgPack      200000         10432 ns/op

我的基准测试代码:

package benchmark

import (
    "encoding/json"
    "github.com/vmihailenco/msgpack"
    "testing"
)

var in = map[string]interface{}{"c": "LOCK", "k": "31uEbMgunupShBVTewXjtqbBv5MndwfXhb", "T/O": 1000, "max": 200}

func BenchmarkJSON(b *testing.B) {
    for i := 0; i < b.N; i++ {
        jsonB := EncodeJSON(in)
        DecodeJSON(jsonB)
    }
}

func BenchmarkMsgPack(b *testing.B) {
    for i := 0; i < b.N; i++ {
        b := EncodeMsgPack(in)
        DecodeMsgPack(b)
    }
}

func EncodeMsgPack(message map[string]interface{}) []byte {
    b, _ := msgpack.Marshal(message)
    return b
}

func DecodeMsgPack(b []byte) (out map[string]interface{}) {
    _ = msgpack.Unmarshal(b, &out)
    return
}

func EncodeJSON(message map[string]interface{}) []byte {
    b, _ := json.Marshal(message)
    return b
}

func DecodeJSON(b []byte) (out map[string]interface{}) {
    _ = json.Unmarshal(b, &out)
    return
}

【讨论】:

    【解决方案2】:

    我建议对机器相互交流的数据类型进行一些基准测试。

    我建议尝试Protocol Buffers(编码)+Snappy(压缩)

    【讨论】:

      【解决方案3】:

      msgpack 只承诺比 json 更短,而不是更快地解析。在这两种情况下,您的测试字符串都非常简短,以至于您的基准测试可能只是测试特定实现的成熟度,而不是底层算法。

      如果您的所有消息真的都这么短,那么解析速度可能是您最不关心的问题。我建议您设计您的服务器,以便解析位易于替换,并实际分析运行中的代码。

      Donald Knuth 对优化做了如下声明:

      “我们应该忘记小的效率,比如大约 97% 的时间:过早的优化是万恶之源”

      最后,如果您真的想知道发生了什么,您需要分析代码。见

      http://blog.golang.org/profiling-go-programs

      有关如何使用 go 分析代码的示例。

      【讨论】:

        【解决方案4】:

        另外,您的测试用例是相反的 BenchmarkJSON 实际调用 MsgPack 和 BenchmarkMsgPack 调用 Json

        这和它有关系吗?

        【讨论】:

        • 是的!你说的对。感谢您注意到它。我已将其反转并将其发布为答案
        猜你喜欢
        • 2016-04-20
        • 2014-09-18
        • 2011-08-18
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多