fernando_fox
2018-07-09 11:25
采纳率: 57.1%
浏览 844
已采纳

java序列化算法C++实现

java.io.Serializable,在哪里能看到这个类的实现代码?我要分析下这个算法,然后用C++实现,不知道现实不?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • 蝴蝶兰琛 2018-07-09 12:13
    已采纳
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • yongxyz 2018-07-09 12:14

    不现实。这是人家的商业机密。正常渠道无法获取。

    评论
    解决 无用
    打赏 举报
  • qq_42589095 2018-07-09 12:14

    import sun.misc.Unsafe;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    import java.lang.reflect.Field;
    import java.nio.ByteBuffer;
    import java.util.Arrays;

    @SuppressWarnings("restriction")
    public final class TestSerialisationPerf {
    public static final int REPETITIONS = 1 * 1000 * 1000;

    private static ObjectToBeSerialised ITEM = new ObjectToBeSerialised(1010L, true, 777, 99,
            new double[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 },
            new long[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
    
    public static void main(final String[] arg) throws Exception {
        for (final PerformanceTestCase testCase : testCases) {
            for (int i = 0; i < 5; i++) {
                testCase.performTest();
    
                System.out.format("%d %s\twrite=%,dns read=%,dns total=%,dns\n", i, testCase.getName(),
                        testCase.getWriteTimeNanos(), testCase.getReadTimeNanos(),
                        testCase.getWriteTimeNanos() + testCase.getReadTimeNanos());
    
                if (!ITEM.equals(testCase.getTestOutput())) {
                    throw new IllegalStateException("Objects do not match");
                }
                System.gc();
                Thread.sleep(3000);
            }
        }
    }
    
    private static final PerformanceTestCase[] testCases = {
            new PerformanceTestCase("Serialisation", REPETITIONS, ITEM) {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
                @Override
                public void testWrite(ObjectToBeSerialised item) throws Exception {
                    for (int i = 0; i < REPETITIONS; i++) {
                        baos.reset();
                        ObjectOutputStream oos = new ObjectOutputStream(baos);
                        oos.writeObject(item);
                        oos.close();
                    }
                }
    
                @Override
                public ObjectToBeSerialised testRead() throws Exception {
                    ObjectToBeSerialised object = null;
                    for (int i = 0; i < REPETITIONS; i++) {
                        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
                        ObjectInputStream ois = new ObjectInputStream(bais);
                        object = (ObjectToBeSerialised) ois.readObject();
                    }
                    return object;
                }
            },
    
            new PerformanceTestCase("ByteBuffer", REPETITIONS, ITEM) {
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                @Override
                public void testWrite(ObjectToBeSerialised item) throws Exception {
                    for (int i = 0; i < REPETITIONS; i++) {
                        byteBuffer.clear();
                        item.write(byteBuffer);
                    }
                }
    
                @Override
                public ObjectToBeSerialised testRead() throws Exception {
                    ObjectToBeSerialised object = null;
                    for (int i = 0; i < REPETITIONS; i++) {
                        byteBuffer.flip();
                        object = ObjectToBeSerialised.read(byteBuffer);
                    }
                    return object;
                }
            },
    
            new PerformanceTestCase("UnsafeMemory", REPETITIONS, ITEM) {
                UnsafeMemory buffer = new UnsafeMemory(new byte[1024]);
                @Override
                public void testWrite(ObjectToBeSerialised item) throws Exception {
                    for (int i = 0; i < REPETITIONS; i++) {
                        buffer.reset();
                        item.write(buffer);
                    }
                }
    
                @Override
                public ObjectToBeSerialised testRead() throws Exception {
                    ObjectToBeSerialised object = null;
                    for (int i = 0; i < REPETITIONS; i++) {
                        buffer.reset();
                        object = ObjectToBeSerialised.read(buffer);
                    }
    
                    return object;
                }
            }
        };
    

    }

    abstract class PerformanceTestCase {
    private final String name;
    private final int repetitions;
    private final ObjectToBeSerialised testInput;
    private ObjectToBeSerialised testOutput;
    private long writeTimeNanos;
    private long readTimeNanos;

    public PerformanceTestCase(final String name, final int repetitions, final ObjectToBeSerialised testInput) {
        this.name = name;
        this.repetitions = repetitions;
        this.testInput = testInput;
    }
    
    public String getName() {
        return name;
    }
    
    public ObjectToBeSerialised getTestOutput() {
        return testOutput;
    }
    
    public long getWriteTimeNanos() {
        return writeTimeNanos;
    }
    
    public long getReadTimeNanos() {
        return readTimeNanos;
    }
    
    public void performTest() throws Exception {
        final long startWriteNanos = System.nanoTime();
        testWrite(testInput);
        writeTimeNanos = (System.nanoTime() - startWriteNanos) / repetitions;
    
        final long startReadNanos = System.nanoTime();
        testOutput = testRead();
        readTimeNanos = (System.nanoTime() - startReadNanos) / repetitions;
    }
    
    public abstract void testWrite(ObjectToBeSerialised item) throws Exception;
    
    public abstract ObjectToBeSerialised testRead() throws Exception;
    

    }

    class ObjectToBeSerialised implements Serializable {
    private static final long serialVersionUID = 10275539472837495L;

    private final long sourceId;
    private final boolean special;
    private final int orderCode;
    private final int priority;
    private final double[] prices;
    private final long[] quantities;
    
    public ObjectToBeSerialised(final long sourceId, final boolean special, final int orderCode, final int priority,
            final double[] prices, final long[] quantities) {
        this.sourceId = sourceId;
        this.special = special;
        this.orderCode = orderCode;
        this.priority = priority;
        this.prices = prices;
        this.quantities = quantities;
    }
    
    public void write(final ByteBuffer byteBuffer) {
        byteBuffer.putLong(sourceId);
        byteBuffer.put((byte) (special ? 1 : 0));
        byteBuffer.putInt(orderCode);
        byteBuffer.putInt(priority);
    
        byteBuffer.putInt(prices.length);
        for (final double price : prices) {
            byteBuffer.putDouble(price);
        }
    
        byteBuffer.putInt(quantities.length);
        for (final long quantity : quantities) {
            byteBuffer.putLong(quantity);
        }
    }
    
    public static ObjectToBeSerialised read(final ByteBuffer byteBuffer) {
        final long sourceId = byteBuffer.getLong();
        final boolean special = 0 != byteBuffer.get();
        final int orderCode = byteBuffer.getInt();
        final int priority = byteBuffer.getInt();
    
        final int pricesSize = byteBuffer.getInt();
        final double[] prices = new double[pricesSize];
        for (int i = 0; i < pricesSize; i++) {
            prices[i] = byteBuffer.getDouble();
        }
    
        final int quantitiesSize = byteBuffer.getInt();
        final long[] quantities = new long[quantitiesSize];
        for (int i = 0; i < quantitiesSize; i++) {
            quantities[i] = byteBuffer.getLong();
        }
    
        return new ObjectToBeSerialised(sourceId, special, orderCode, priority, prices, quantities);
    }
    
    public void write(final UnsafeMemory buffer) {
        buffer.putLong(sourceId);
        buffer.putBoolean(special);
        buffer.putInt(orderCode);
        buffer.putInt(priority);
        buffer.putDoubleArray(prices);
        buffer.putLongArray(quantities);
    }
    
    public static ObjectToBeSerialised read(final UnsafeMemory buffer) {
        final long sourceId = buffer.getLong();
        final boolean special = buffer.getBoolean();
        final int orderCode = buffer.getInt();
        final int priority = buffer.getInt();
        final double[] prices = buffer.getDoubleArray();
        final long[] quantities = buffer.getLongArray();
    
        return new ObjectToBeSerialised(sourceId, special, orderCode, priority, prices, quantities);
    }
    
    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
    
        final ObjectToBeSerialised that = (ObjectToBeSerialised) o;
    
        if (orderCode != that.orderCode) {
            return false;
        }
        if (priority != that.priority) {
            return false;
        }
        if (sourceId != that.sourceId) {
            return false;
        }
        if (special != that.special) {
            return false;
        }
        if (!Arrays.equals(prices, that.prices)) {
            return false;
        }
        if (!Arrays.equals(quantities, that.quantities)) {
            return false;
        }
    
        return true;
    }
    

    }

    @SuppressWarnings("restriction")
    class UnsafeMemory {

    private static final Unsafe unsafe;
    
    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    private static final long byteArrayOffset = unsafe.arrayBaseOffset(byte[].class);
    private static final long longArrayOffset = unsafe.arrayBaseOffset(long[].class);
    private static final long doubleArrayOffset = unsafe.arrayBaseOffset(double[].class);
    
    private static final int SIZE_OF_BOOLEAN = 1;
    private static final int SIZE_OF_INT = 4;
    private static final int SIZE_OF_LONG = 8;
    
    private int pos = 0;
    private final byte[] buffer;
    
    public UnsafeMemory(final byte[] buffer) {
        if (null == buffer) {
            throw new NullPointerException("buffer cannot be null");
        }
    
        this.buffer = buffer;
    }
    
    public void reset() {
        this.pos = 0;
    }
    
    public void putBoolean(final boolean value) {
        unsafe.putBoolean(buffer, byteArrayOffset + pos, value);
        pos += SIZE_OF_BOOLEAN;
    }
    
    public boolean getBoolean() {
        boolean value = unsafe.getBoolean(buffer, byteArrayOffset + pos);
        pos += SIZE_OF_BOOLEAN;
        return value;
    }
    
    public void putInt(final int value) {
        unsafe.putInt(buffer, byteArrayOffset + pos, value);
        pos += SIZE_OF_INT;
    }
    
    public int getInt() {
        int value = unsafe.getInt(buffer, byteArrayOffset + pos);
        pos += SIZE_OF_INT;
        return value;
    }
    
    public void putLong(final long value) {
        unsafe.putLong(buffer, byteArrayOffset + pos, value);
        pos += SIZE_OF_LONG;
    }
    
    public long getLong() {
        long value = unsafe.getLong(buffer, byteArrayOffset + pos);
        pos += SIZE_OF_LONG;
        return value;
    }
    
    public void putLongArray(final long[] values) {
        putInt(values.length);
        long bytesToCopy = values.length << 3;
        unsafe.copyMemory(values, longArrayOffset, buffer, byteArrayOffset + pos, bytesToCopy);
        pos += bytesToCopy;
    }
    
    public long[] getLongArray() {
        int arraySize = getInt();
        long[] values = new long[arraySize];
        long bytesToCopy = values.length << 3;
        unsafe.copyMemory(buffer, byteArrayOffset + pos, values, longArrayOffset, bytesToCopy);
        pos += bytesToCopy;
    
        return values;
    }
    
    public void putDoubleArray(final double[] values) {
        putInt(values.length);
        long bytesToCopy = values.length << 3;
        unsafe.copyMemory(values, doubleArrayOffset, buffer, byteArrayOffset + pos, bytesToCopy);
        pos += bytesToCopy;
    }
    
    public double[] getDoubleArray() {
        int arraySize = getInt();
        double[] values = new double[arraySize];
    
        long bytesToCopy = values.length << 3;
        unsafe.copyMemory(buffer, byteArrayOffset + pos, values, doubleArrayOffset, bytesToCopy);
        pos += bytesToCopy;
    
        return values;
    }
    

    }

    评论
    解决 无用
    打赏 举报
  • 哆啦一只喵 2018-07-09 18:43
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题