首页 > 解决方案 > 使用protobuf在java中发送19位长数组列表的最有效方法是什么

问题描述

我正在尝试使用 protobuf 发送一个包含 1000 个长数字和 19 位数字的数组列表。我使用了重复的 fixed64 作为数据类型,因为它推荐用于通常大于 2^56 的数字,并且它使用 8 字节的固定编码。我的原型格式是

message ListLong {
    repeated fixed64 value = 1;
}

我使用以下方法创建了原型对象。

static ListLong createListOfLong(List<Long> longList) {
    ListLong.Builder list = ListLong.newBuilder();
    for(long value : longList) {
        list.addValue(value);
    }
    return list.build();
}

我序列化了这条包含 1000 个长值的消息并转换为字节数组。字节数组的大小为8004字节。我用以下方法测量了对象创建和序列化前后的处理时间、CPU使用时间和分配的内存。

ThreadMXBean tmx = (ThreadMXBean) ManagementFactory.getThreadMXBean();
Long cpuStartTime = tmx.getCurrentThreadCpuTime();
Long startMemory = tmx.getThreadAllocatedBytes(Thread.currentThread().getId());
Long startTime = System.currentTimeMillis();
Long protoList = createListOfLong(collectionList);
System.out.println("Cpu usage time for proto creation  "+(tmx.getCurrentThreadCpuTime()-cpuStartTime)/1000000+"ms");
System.out.println("Heap Memory usage for proto creation  "+(tmx.getThreadAllocatedBytes(Thread.currentThread().getId())-startMemory)/1000+"KB");
System.out.println("object creation time is "+(System.currentTimeMillis()-startTime)+" ms");
startMemory = tmx.getThreadAllocatedBytes(Thread.currentThread().getId());
cpuStartTime = tmx.getCurrentThreadCpuTime();
startTime = System.currentTimeMillis();
byte[] b = protoList.toByteArray();
System.out.println("Heap Memory usage for serializing  "+(tmx.getThreadAllocatedBytes(Thread.currentThread().getId())-startMemory)/1000+"KB");
System.out.println("Serialized time is "+(System.currentTimeMillis()-startTime)+" ms");
System.out.println("Cpu usage time for serializing  "+(tmx.getCurrentThreadCpuTime()-cpuStartTime)/1000000+"ms");

在intellij ide中使用时得到以下参数。

Cpu usage time for proto creation  54ms
Heap Memory usage for proto creation  5756KB
object creation time is 56 ms
Heap Memory usage for serializing  3090KB
Serialized time is 29 ms
Cpu usage time for serializing  28ms
Serialized length is is 8004

我的问题是

  1. 是否有任何替代消息格式来发送ArrayList19 位长的?

  2. 我们能以任何方式实现小于 8k 的字节数组长度吗?

  3. 为什么 protobuf 对象创建需要大量处理时间和内存?

  4. 有什么方法可以减少处理时间和分配的内存?

标签: javaperformanceserializationprotocol-buffersprotobuf-java

解决方案


推荐阅读