Java:Protobuf字节快速转换为Json字符串

rn0zuynd  于 2023-01-03  发布在  Java
关注(0)|答案(1)|浏览(255)

我正在接收protobuf格式的消息。我需要将其转换为json格式fast,因为我所有的业务逻辑都是为了处理基于json的POJO对象而编写的。

byte[] request = ..; // msg received

// convert to intermediate POJO
AdxOpenRtb.BidRequest bidRequestProto = AdxOpenRtb.BidRequest.parseFrom(request, reg);

// convert intermediate POJO to json string.
// THIS STEP IS VERY SLOW
Printer printer = JsonFormat.printer().printingEnumsAsInts().omittingInsignificantWhitespace();
String jsonBody = printer.print(bidRequestProto);

// convert json string to final POJO format
BidRequest bidRequest = super.parse(jsonBody.getBytes());

从原型对象到json的转换非常慢,有没有更快的方法?
我可以重用printer对象吗?它是线程安全的吗?

注:此POJO类(AdxOpenRtb.BidRequestBidRequest)非常复杂,具有许多层次结构和字段,但包含字段名称和数据类型略有不同的类似数据

bybem2ql

bybem2ql1#

我也遇到了一些性能问题,最后编写了QuickBuffers库。它生成专用的JSON序列化方法(即没有反射),应该会给你带来10- 30倍的加速。它可以与Google的实现一起使用。代码应该如下所示:

// Initialization (objects can be reused if desired)
    AdxOpenRtb.BidRequest bidRequestProto = AdxOpenRtb.BidRequest.newInstance();
    ProtoSource protoSource = ProtoSource.newArraySource();
    JsonSink jsonSink = JsonSink.newInstance().setWriteEnumsAsInts(true);

    // Convert Protobuf to JSON
    bidRequestProto.clearQuick() // or ::parseFrom if you want a new object
            .mergeFrom(protoSource.setInput(request))
            .writeTo(jsonSink.clear());

    // Use the raw json bytes
    RepeatedByte jsonBytes = jsonSink.getBytes();

JsonSinkBenchmark提供了一些示例代码,用于将内置JSON编码器替换为经过更多实际测试的Gson/Jackson后端。

编辑:如果您在单个进程中执行此操作,并且担心性能,那么最好编写或生成代码来直接转换Java对象,JSON不是一种非常高效的格式。

相关问题