Communication protocol serialization interpretation (2) protostuff detailed tutorial

Previous article Interpretation of Communication Protocol Serialization (1) : http://www.cnblogs.com/tohxyblog/p/8974641.html 

Foreword : In the previous article, we introduced java serialization and Google protobuf, but because the use of protobuf is not as simple as other serialization (first write the .proto file, then compile the .proto file to generate the corresponding .java file ), so no matter how good he is, he still failed to seize the share of json.
In this article, we are going to introduce a protobuf-based java serialization protocol - prorostuff, which can be very easy to use on the java side, and deserialization can be done by protobuf (then the front end can be decoded by protobuf in other languages) .

1. Introduction to protostuff

protostuff is based on Google protobuf, but provides more functionality and easier usage. Among them, protostuff-runtime realizes the ability of protobuf serialization/deserialization of java beans without precompiling. The limitation of protostuff-runtime is that schema needs to be passed in before serialization, and deserialization is not responsible for object creation but only for copying, so a default constructor must be provided. In addition, protostuff can also be serialized into json/yaml/xml formats according to the configuration of protobuf.

In terms of performance, protostuff does not lose to native protobuf, and even has the potential to surpass it.

2. Protostuff features

  1. Support for messages generated by protostuff-compiler

  2. Support for existing POJOs

  3. Support for Java messages generated by existing protoc

  4. Interoperability with various mobile platforms (Android, Kindle, j2me)

  5. Support transcoding

3. Tool class implementation

Guide package:

<!-- //protostuff serialization-->
	<dependency>  
     <groupId>com.dyuproject.protostuff</groupId>  
     <artifactId>protostuff-core</artifactId>  
     <version>1.0.8</version>  
 </dependency>  
 <dependency>  
     <groupId>com.dyuproject.protostuff</groupId>  
     <artifactId>protostuff-runtime</artifactId>  
     <version>1.0.8</version>  
 </dependency>  
 <!-- Objenesis -->
 <dependency>
     <groupId>org.objenesis</groupId>
     <artifactId>objenesis</artifactId>
     <version>2.1</version>
 </dependency>

 

 

Tools:

package com.result.base.tools;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.objenesis.Objenesis;
import org.objenesis.ObjenesisStd;

import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtobufIOUtil;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;


/**
* @author by huangxinyu
* @version created: Jan 9, 2018 7:41:24 PM
* Protostuff serialization tool
*/
public class SerializationUtil {
	private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<>();

    private static Objenesis objenesis = new ObjenesisStd(true);

    private SerializationUtil() {
    }

    @SuppressWarnings("unchecked")
    private static <T> Schema<T> getSchema(Class<T> cls) {
        Schema<T> schema = (Schema<T>) cachedSchema.get(cls);
        if (schema == null) {
            schema = RuntimeSchema.createFrom(cls);
            if (schema != null) {
                cachedSchema.put(cls, schema);
            }
        }
        return schema;
    }

    @SuppressWarnings("unchecked")
    public static <T> String serializeToString(T obj) {
        Class<T> cls = (Class<T>) obj.getClass();
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            Schema<T> schema = getSchema(cls);
            return new String(ProtobufIOUtil.toByteArray(obj, schema, buffer), "ISO8859-1");
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            buffer.clear();
        }
    }

    public static <T> T deserializeFromString(String data, Class<T> cls) {
        try {
            T message = (T) objenesis.newInstance(cls);
            Schema<T> schema = getSchema(cls);
            ProtobufIOUtil.mergeFrom(data.getBytes("ISO8859-1"), message, schema);
            return message;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
    

    @SuppressWarnings("unchecked")
    public static <T> byte[] serializeToByte(T obj) {
        Class<T> cls = (Class<T>) obj.getClass();
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        try {
            Schema<T> schema = getSchema(cls);
            return ProtobufIOUtil.toByteArray(obj, schema, buffer);
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            buffer.clear();
        }
    }

    public static <T> T deserializeFromByte(byte[] data, Class<T> cls) {
        try {
            T message = (T) objenesis.newInstance(cls);
            Schema<T> schema = getSchema(cls);
            ProtobufIOUtil.mergeFrom(data, message, schema);
            return message;
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
}

  

4. Performance test

4.1 Test Environment

xstraem version: 1.3.1

protobuf-java version: 3.0.0-alpha-2

java version: 1.7

-Xms2048m

-Xmx2048m

 

4.2 Test Tools

Time: console output time

CPU & Memory: jconsole

file size: file properties

 

4.3 Description

In the test, the JavaBeans used in the three tests, xml, protoBuf and protostuff, have the same field type, the same number of fields (about 28), the same value attached to the field, and all contain a List<String> field. The size of the field controls the size of the JavaBean object. In this test size=100

 

4.4 Results

Test A: 10000 objects

 

 

xstream

protobuf

protostuff

Serialization

Time (ms)

2399

648

261

Occupied CPU (%)

24.2

12.3

3.4

Occupied memory (M)

154

235

92

Size of each file (byte)

2822

574

574

 

deserialize

Time (ms)

3378

167

224

CPU usage (%)

15.9

14.2

6.1

Occupied memory (M)

248

307

164

Remarks: 10000 objects

 

Test B: 25000 objects

 

xstream

protobuf

protostuff

Serialization

Time (ms)

4161

767

293

Occupied CPU (%)

31.2

14.6

4.7

Occupied memory (M)

495

228

194

Size of each file (byte)

2822

574

574

 

deserialize

Time (ms)

6941

252

393

CPU usage (%)

31.9

21.9

8.1

Occupied memory (M)

411

382

348

Remarks: 25000 objects

Test C: 100000 objects

 

xstream

protobuf

protostuff

Serialization

Time (ms)

12867

3070

704

Occupied CPU (%)

42.5

44.9

22.3

Occupied memory (M)

1098

1058

572

Size of each file (byte)

2822

574

574

 

deserialize

Time (ms)

24442

4540

1522

CPU usage (%)

38.8

68.2

24.1

Occupied memory (M)

2215

597

870

Remarks: 50000 objects

Quoting the histogram of the last set of data:

4.5 Conclusion

1. Serialization:

  1.1. In terms of speed: protostuff is about 3 times faster than protobuf, and protobuf is 4-5 times faster than xml. The multiple remains basically unchanged with the increase of serialized objects.

  1.2. On the CPU: protostuff occupies the least, protobuf second, and xml last.

  1.3. In terms of memory: protostuff occupies the least, protobuf is the second, and xml is the last.

  1.4. Generated file size: protostuff occupies the least, protobuf second, xml last, the first two are about 1/4 of the latter.

2. Deserialization

  2.1. Speed: In the case of a small number of deserialized objects, protobuf is about 1/4 faster than protostuff and 10+ times faster than xml. But as the number of objects increases, protobuf happens to noticeably slow down! Thus being overtaken by protostuff.

  2.2. On the CPU: protostuff occupies the least, protobuf second, and xml last.

  2.3. In terms of memory: protostuff occupies the least, protobuf is the second, and xml is the last.

3. Summary

  In all aspects, the advantages of protostuff are very interview, and protobuf is not weak, consider using it instead of xml.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325160821&siteId=291194637