Protostuff序列化与反序列化,反序列化时无须传入类

本文探讨了ProtostuffSerializer与Kryo在序列化性能上的对比,展示了在高并发场景下,ProtostuffSerializer在执行效率和序列化后的字节大小上不如Kryo。作者分享了代码实例并提出了MD5转换类ID的性能优化点。
摘要由CSDN通过智能技术生成
/**
 * 与kryo对比,都是启用新线程,每隔1秒执行10000次,执行效率和序列化后的字节大小都是kryo完胜
 *
 * @author zkpursuit
 */
public class ProtostuffSerializer<T> implements Serializer<T> {
    private static final Map<Long, Schema<?>> schemaCache = new ConcurrentHashMap<>();

    private static <T> Schema<T> getSchema(Class<T> clazz, long clazzId) {
        Schema<T> schema = (Schema<T>) schemaCache.get(clazzId);
        if (Objects.isNull(schema)) {
            schema = RuntimeSchema.getSchema(clazz);
            if (Objects.nonNull(schema)) {
                schemaCache.put(clazzId, schema);
            }
        }
        return schema;
    }

    private static <T> Schema<T> getSchema(long typeId) {
        return (Schema<T>) schemaCache.get(typeId);
    }

    @Override
    public byte[] serialize(T obj) {
        Class<T> clazz = (Class<T>) obj.getClass();
        String className = clazz.getTypeName();
        long classId = StringUtils.toNumber(className); //将类的唯一限定名转换为唯一ID,实现原理是将字符串转为MD5后再转为long型数字,由于一个项目中类数量限制,MD5的重复命中可以忽略,由于算法本身缘故,会有一点性能损耗,有待优化。
        Schema<T> schema = getSchema(clazz, classId);
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); //此处可优化为使用对象池
        byte[] data = ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        buffer.clear();
        byte[] typeIdBytes = ByteUtils.getBytes(classId);
        byte[] bytes = new byte[8 + data.length]; //将类的唯一id写入序列化字节数组首部,固定占用8个字节
        System.arraycopy(typeIdBytes, 0, bytes, 0, typeIdBytes.length);
        System.arraycopy(data, 0, bytes, typeIdBytes.length, data.length);
        return bytes;
    }

    @Override
    public T deserialize(byte[] bytes) {
        long id = ByteUtils.toLong(bytes, 0); //解析出首部8字节的唯一类名ID
        Schema<T> schema = getSchema(id);
        if (schema == null) return null;
        byte[] data = new byte[bytes.length - 8];
        System.arraycopy(bytes, 8, data, 0, data.length);
        T obj = schema.newMessage();
        ProtostuffIOUtil.mergeFrom(data, obj, schema);
        return obj;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值