Ускорение операций глубокого копирования Java - PullRequest
5 голосов
/ 02 сентября 2010

Мы реализовали механизм глубокого копирования общего назначения с использованием сериализации.

import java.io.*;

public class CopyUtil {

    public static Object clone(Object source) {
        Object retVal = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(source);
            oos.flush();
            oos.close();

            ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
            retVal = in.readObject();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }

        return retVal;
    }
}

Существует относительно большое количество классов объектов, которые постоянно развиваются, чтобы их поддерживать. Именно по этой причине мы применили механизм клонирования общего назначения. Нам не нравилась идея поддерживать readObject() и writeObject() на 200+ классах.

К сожалению, механизм сериализации в Java относительно медленный, и у нас возникают проблемы, когда наша система находится в пиковой нагрузке.

Существуют ли какие-либо предлагаемые подходы о том, как можно немного ускорить процесс или (в случае неправильного выполнения этого) альтернативные методы клонирования объектов?

Ответы [ 2 ]

6 голосов
/ 02 сентября 2010

Более быстрая альтернатива сериализации реализована в Hibernate (в частности, в кеше 2-го уровня);Я не знаю деталей, но вы можете проверить исходный код.

Возможно, вы знаете, что интерфейс clone() не работает, поэтому его лучше избегать, если только нет действительно веской причины для использованияЭто.От Effective Java 2nd Edition , Item 11: Разумное переопределение клона

Учитывая все проблемы, связанные с Cloneable, можно с уверенностью сказать, что другиеинтерфейсы не должны расширять его, и классы, предназначенные для наследования (пункт 17), не должны его реализовывать.Из-за множества недостатков некоторые опытные программисты просто предпочитают никогда не переопределять метод clone и никогда не вызывать его, за исключением, возможно, копирования массивов.Если вы разрабатываете класс для наследования, имейте в виду, что если вы решите не предоставлять защищенный метод clone с хорошим поведением, для подклассов будет невозможно реализовать Cloneable.

Обновление:При мелком / глубоком клонировании

С API-интерфейс clone () :

Создает и возвращает копию этого объекта.Точное значение «копия» может зависеть от класса объекта.[...]

По соглашению объект, возвращаемый этим методом, должен быть независимым от этого объекта (который клонируется).Для достижения этой независимости может потребоваться изменить одно или несколько полей объекта, возвращаемого super.clone, перед его возвратом.Как правило, это означает копирование любых изменяемых объектов, которые составляют внутреннюю «глубокую структуру» клонируемого объекта, и замену ссылок на эти объекты ссылками на копии.Если класс содержит только примитивные поля или ссылки на неизменяемые объекты, то обычно бывает так, что нет необходимости изменять поля в объекте, возвращаемом super.clone.

Таким образом, на самом деле соглашениеэто сделать глубокую копию.

Тем не менее, предпочтительной альтернативой является определение конструктора копирования или независимого метода вместо переопределения clone().

2 голосов
/ 02 сентября 2010

Вы можете проверить Библиотека глубокого клонирования . Я не знаю, как это реализовано, но вы можете обнаружить, что это более быстрое решение.

Хотя это не относится к скорости, этот вопрос имеет некоторые соответствующие ресурсы, которые стоит изучить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...