Использование DataTypeFactory при создании XMLGregorianCalendar сильно снижает производительность - PullRequest
12 голосов
/ 08 сентября 2011

Учитывая время в миллисекундах, мы можем создать XMLGregorianCalendar, используя следующий фрагмент.

GregorianCalendar greCal = new GregorianCalendar();
greCal.setTimeInMillis(timeInMilliseconds);
XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(greCal));

Но проблема в том, что это плохо сказывается на производительности.

http://www.java.net/node/666491

Для SUN подана ошибка, но они не нашли обходных путей. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6466177

Пробовал искать какую-то другую альтернативу, но тщетно. У кого-нибудь из вас есть альтернатива, чтобы сделать то же самое?

Спасибо

комбинационное

Ответы [ 2 ]

12 голосов
/ 25 мая 2012

Дорогая часть - DatatypeFactory.newInstance (), она отображается справа вверху при профилировании приложения. В нашем случае мы сохранили DatatypeFactory как статическую переменную и смогли обойти повторную инициализацию. Это должно работать, потому что используемая нами реализация DatatypeFactory должна быть поточно-ориентированной (как указано в отчете об ошибке). Я согласен, что есть вероятность, что это может измениться в зависимости от используемой реализации. Поэтому я рекомендую дважды проверить.

private static DatatypeFactory datatypeFactory;
static{
    try {
        datatypeFactory = DatatypeFactory.newInstance();
    } catch (DatatypeConfigurationException e) {
        throw new RuntimeException("Init Error!", e);
    }
}

public void foo(long timeInMilliseconds){
    GregorianCalendar greCal = new GregorianCalendar(); greCal.setTimeInMillis(timeInMilliseconds); 
    XMLGregorianCalendar xmlGregorienCalendar = datatypeFactory.newXMLGregorianCalendar(greCal);
    // ...
}
9 голосов
/ 15 марта 2013

Поскольку, как упоминалось @VivaceVivo, DataFactory.newInstance () является дорогостоящим и подразумевает, что он не гарантирует многопоточность, рассмотрите возможность использования ThreadLocal:

final private static ThreadLocal<DatatypeFactory> datatypeFactoryHolder = new ThreadLocal<DatatypeFactory>()
    {
        @Override
        protected DatatypeFactory initialValue()
        {
            try
            {
                return DatatypeFactory.newInstance();
            } catch (DatatypeConfigurationException e)
            {
                throw new IllegalStateException("failed to create " + DatatypeFactory.class.getSimpleName(), e);
            }
        }
    };

    public static XMLGregorianCalendar dateToXMLGregorianCalendar(Date date)
    {
        GregorianCalendar c = new GregorianCalendar();
        c.setTime(date);
        return datatypeFactoryHolder.get().newXMLGregorianCalendar(c);
    }
}

.. до тех пор, пока вам все равно, сохранят ли потоки дополнительный объект или имеют способ очистки ThreadLocalMap при необходимости

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