наследование - сериализация в xml java




Java: эффективность writeObject против writeExternal (2)

В выборе класса / writeObject / readObject для вызова следующего все еще есть некоторые накладные расходы. но это значительно снижается.

Это может работать так же, как Externalizable, в зависимости от того, что вы делаете, и используете ли вы дополнительные опции, которые он вам дает. Например, readObject предполагает, что вы создаете новый объект каждый раз, Externalizable имеет readResolve, что означает, что вы можете повторно использовать объекты.

http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/input.html

Во многих случаях утилизация объектов является «следующим» шагом в ускорении десериализации. (Предполагая, что это вариант для вас)

http://vanillajava.blogspot.co.uk/2011/10/recycling-objects-to-improve.html

Говорят, что механизм сериализации Java по умолчанию не очень эффективен, потому что: а) он обнаруживает, какие поля для записи / чтения через отражение, что обычно медленно, б) записывает дополнительные данные в поток.

Один из способов сделать его более эффективным - реализовать Externalizable и его методы writeExternal / readExternal.

Вот вопрос: если я вместо этого предоставлю методы writeObject / readObject и не вызову в них deafiltWriteObject / defaultReadObject, то этот механизм не будет использовать отражение, чтобы выяснить, какие поля записывать / читать, плюс он не будет писать дополнительные данные для потоковой передачи (или это будет? не уверен). Итак, с точки зрения эффективности, является ли реализация writeObject / readObject, упомянутая выше, такой же, как реализация Externalizable? Или последний вариант дает больше практических преимуществ, которых нет у первого?

РЕДАКТИРОВАТЬ: различие, конечно, заключается в том, что класс Serializable, реализующий readObject / writeObject, является подклассом, и если у подкласса есть свой собственный readObject / writeObject, им не нужно вызывать супер-readObject / writeObject. Не так, если супер / подкласс вместо этого реализует Externalizable. В этом случае super's writeExternal / readExternal необходимо вызывать явно. Однако это различие не имеет значения с точки зрения эффективности.


Обнаружил несколько вещей во время экспериментов и прохождения кода механизма сериализации:

1) если объект признан Externalizable, он приводится к Externalizable, и для него вызывается соответствующий метод; тогда как для объекта Serializable, он рефлекторно проверяется, имеет ли он readObject / writeObject. Так что, может быть, это немного замедляет,

2) объем данных, записанных для Externalizable, немного меньше, чем для Serializable с readObject / writeObject (я нашел разницу в 1 байт для следующего кода, когда писал объект B).

Для 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");
    }       
}

Для сериализуемых:

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");
    }       
}




serialization