examples - Java: la eficiencia de writeObject vs writeExternal
serialversionuid (3)
Encontré un par de cosas al experimentar y pasar por el código del mecanismo de serialización:
1) si se encuentra que el objeto es Externalizable, se convierte en Externalizable, y se invoca el método correspondiente; mientras que para el objeto Serializable, se comprueba de manera reflexiva si tiene readObject / writeObject. Así que tal vez esto lo hace un poco más lento,
2) la cantidad de datos escritos para Externalizable es un poco menor que Serializable con readObject / writeObject (Encontré una diferencia de 1 byte para el siguiente código cuando escribí el objeto B).
Para externalizable:
static class A implements Externalizable
{
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
System.out.println("A write called");
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
System.out.println("A read called");
}
}
static class B extends A implements Externalizable
{
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
super.writeExternal(out);
System.out.println("B write called");
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
super.readExternal(in);
System.out.println("B read called");
}
}
Para Serializable:
static class A implements Serializable
{
private void writeObject(ObjectOutputStream out) throws IOException
{
System.out.println("A write called");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
System.out.println("A read called");
}
}
static class B extends A implements Serializable
{
private void writeObject(ObjectOutputStream out) throws IOException
{
System.out.println("B write called");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
System.out.println("B read called");
}
}
Se dice que el mecanismo de serialización predeterminado de Java no es muy eficiente porque a) descubre qué campos escribir / leer a través de la reflexión, que generalmente es lento b) escribe datos adicionales para transmitir.
Una forma de hacerlo más eficiente es implementar Externalizable y sus métodos writeExternal / readExternal.
Aquí está la pregunta: si en su lugar proporciono métodos ''writeObject / readObject'' y no llamo deafiltWriteObject / defaultReadObject en ellos, entonces este mecanismo no usará la reflexión para descubrir qué campos escribir / leer, además no escribirá más Datos para transmitir (¿o no? No estoy seguro). Entonces, desde una perspectiva de eficiencia, ¿la implementación de writeObject / readObject mencionada anteriormente es lo mismo que implementar Externalizable? ¿O la última opción da algunos beneficios más prácticos que la anterior no?
EDITAR: una diferencia, por supuesto, es cuando una clase Serializable que implementa readObject / writeObject se clasifica en una subclase, y si la subclase tiene su propio readObject / writeObject, no es necesario que llamen a read''s superObject / writeObject No es así si la super / subclase implementa Externalizable. En este caso, es necesario llamar explícitamente a los sobres writeExternal / readExternal. Sin embargo, esta diferencia es irrelevante desde el punto de vista de la eficiencia.
La principal diferencia, en términos de diseño de clase, es que Serializable
funcionará en cualquier clase, mientras que Externalizable
solo funciona en clases mutables con constructores públicos predeterminados (no-arg).
Todavía hay un poco de ventaja al elegir a qué clase / writeObject / readObject llamar a continuación. pero se reduce significativamente.
Esto puede realizar lo mismo que Externalizable dependiendo de lo que esté haciendo y de si usa las opciones adicionales que le ofrece. Por ejemplo, readObject supone que creas un nuevo objeto cada vez, Externalizable tiene readResolve, lo que significa que puedes reutilizar objetos.
http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/input.html
En muchos casos, el reciclaje de objetos es el "siguiente" paso para acelerar la deserialización. (Suponiendo que esa es una opción para ti)
http://vanillajava.blogspot.co.uk/2011/10/recycling-objects-to-improve.html