Externalizable stores more data than Serializable ?

When trying to optimize some code (to reduce the amount of data transferred), i changed my class from Serializble to Externalizable. The methods required by Externalizable read/write a single int value. To my surprise this changed the number of bytes from 1310861 to 1704069! Does anybody know what I am doing wrong here?

import java.io.*;

publicclass SerializationTest{

publicstaticvoid main(String[] args){

try{

/* This uses Serializable

SimpleObject1[] objects = new SimpleObject1[128*1024];

for (int i=0; i<128*1024; ++i){

objects[i] = new SimpleObject1(i);

}

*/

// This used Externalizable

SimpleObject2[] objects =new SimpleObject2[128*1024];

for (int i=0; i<128*1024; ++i){

objects[i] =new SimpleObject2(i);

}

ByteArrayOutputStream byteOut =new ByteArrayOutputStream(10000000);

ObjectOutputStream objectOut =new ObjectOutputStream(new BufferedOutputStream(byteOut));

objectOut.flush();

long startTime = System.nanoTime();

objectOut.writeObject(objects);

objectOut.flush();

double totalTime = (System.nanoTime() - startTime) / 1E9;

byte[] buffer = byteOut.toByteArray();

System.out.println("Bytes written: " + buffer.length);

System.out.println("Total time: " + totalTime);

}catch (Exception e){

}

}

}

class SimpleObject1implements Serializable{

privateint value;

public SimpleObject1(){

super();

}

public SimpleObject1(int i){

super();

this.value = i;

}

}

class SimpleObject2implements Externalizable{

privateint value;

public SimpleObject2(){

super();

}

public SimpleObject2(int i){

super();

this.value = i;

}

publicvoid readExternal(ObjectInput in)throws IOException, ClassNotFoundException{

this.value = in.readInt();

}

publicvoid writeExternal(ObjectOutput out)throws IOException{

out.writeInt(this.value);

}

}

[4268 byte] By [MN3M0N1CSa] at [2007-11-26 16:01:17]
# 1

To my knowledge externalizable dosent really do anything to reduse the space taken. It only gives you more controll of the process.

Also when writing a externzlised objects in to stream it will write class discriptors of both Serializable and Externalizable to stream. when writing Serialisable only Serialisable class discriptor is written this will cause additional data.

If you want smaller files sizes use compression or your own optiomized protocols to store objects.

Ex:- All the data belong to 100 SimpleObject2 instances can be stored in just using one int array with 100 elements.

LRMKa at 2007-7-8 22:22:52 > top of Java-index,Java Essentials,Java Programming...
# 2

Thank you for your reply. The thing I don't understand is

"Also when writing a externzlised objects in to stream it will write class discriptors of both Serializable and Externalizable to stream"

does this mean each externalizable object has two class descriptors instead of only one for serializable objects? This could explain the difference in size. Is there a way to circumvent writing one (or even both) of these class descriptors?

MN3M0N1CSa at 2007-7-8 22:22:52 > top of Java-index,Java Essentials,Java Programming...
# 3

Nope.

When writing an object in to a object stream its not only the objects data that is written. Also the information about the objects class, super classes and interfaces that those classes implement are also written becouse those information are required at the read end in order to reliabily reconstruct the object.

More super classes, interfaces the objec thas more information written to stream.

In Externzlisable case the interface Externzlisable extends Serialisable interfece. So every objec tthat implement the Externzlisable also implements the Serialisable. As a result both the class descriptiors will be written when the object is serialised.

If you try the following code you will see that the

objec tof the derived class take more space even though it has not defined any data elements.

import java.io.*;

public class test2 {

public static void writeTest(Object obj)throws Exception{

ByteArrayOutputStream baos = new ByteArrayOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(baos);

oos.writeObject(obj);

oos.close();

System.out.println("Size [" + obj.getClass() + "]: " + baos.toByteArray().length);

}

public static void main (String args[]) throws Exception{

writeTest(new Cls1());

writeTest(new Cls2());

}

static class Cls1 implements Externalizable{

public int i1;

public void readExternal(ObjectInput in)throws IOException{

i1 = in.readInt();

}

public void writeExternal(ObjectOutput out)throws IOException{

out.writeInt(i1);

}

}

static class Cls2 extends Cls1{

}

}

LRMKa at 2007-7-8 22:22:52 > top of Java-index,Java Essentials,Java Programming...