Java: нужна помощь с оптимизацией части кода

У меня есть простой код для преобразования XML, но он занимает очень много времени (мне приходится повторять его много раз). У кого-нибудь есть рекомендации, как оптимизировать этот код? Спасибо.

EDIT: это новая версия кода. К сожалению, я не могу повторно использовать Transformer, так как XSLTRule в большинстве случаев отличается. Сейчас я повторно использую TransformerFactory. Я не читаю файлы до этого, поэтому не могу использовать StreamSource. Наибольшее количество времени тратится на инициализацию Transformer.

private static TransformerFactory tFactory = TransformerFactory.newInstance();

public static String transform(String XML, String XSLTRule) throws TransformerException {

    Source xmlInput = new StreamSource(new StringReader(XML));
    Source xslInput = new StreamSource(new StringReader(XSLTRule));

    Transformer transformer = tFactory.newTransformer(xslInput);

    StringWriter resultWriter = new StringWriter();
    Result result = new StreamResult(resultWriter);
    transformer.transform(xmlInput, result);
    return resultWriter.toString();
}

person Ivan    schedule 02.05.2011    source источник
comment
Каждый раз разные файлы XSL? Если нет, кэшируйте преобразователь. Кроме того, этот код медленный сам по себе? Какой спектакль вы видите?   -  person Joseph Ottinger    schedule 02.05.2011
comment
Каждый раз это другой XML, но XSLT повторяются (хотя их много). Я использую профилировщик, и он говорит, что на этот метод тратится куча времени.   -  person Ivan    schedule 02.05.2011
comment
Где в этом методе? Компиляция XSLT часто выполняется медленно, но если это не то, на что нужно тратить время... посмотрите на opensymphony.com/ OSCore, так как в нем есть несколько оптимизированных XML-утилит, которые будут кэшировать преобразователи, если смогут.   -  person Joseph Ottinger    schedule 02.05.2011
comment
@Joseph Наибольшее количество времени тратится на инициализацию Transformer. Буду думать как сделать кеш. Спасибо.   -  person Ivan    schedule 02.05.2011


Ответы (4)


Первое, что вы должны сделать, это пропустить ненужное преобразование строки XML в байты (особенно с жестко заданной, потенциально неправильной кодировкой). Вы можете использовать StringReader и передать его конструктору StreamSource. То же самое для результата: используйте StringWriter и избегайте преобразования.

Конечно, если вы вызываете метод после преобразования вашего XML из файла (байтов) в String в первую очередь (опять же с потенциально неправильной кодировкой), было бы еще лучше, чтобы StreamSource читалось из файла напрямую.

person Michael Borgwardt    schedule 02.05.2011
comment
+1: ненужное преобразование формата может привести к потере большого количества времени. И они могут легко ввести уродливые ошибки. - person Joachim Sauer; 02.05.2011
comment
@Ivan: вы все еще делаете ненужное и, вероятно, разрушительное преобразование String -> byte -> String в потоке результатов. И да, кэширование экземпляров преобразователя может значительно улучшить ситуацию, в зависимости от того, как часто встречается один и тот же XSLT. - person Michael Borgwardt; 02.05.2011

Похоже, вы применяете XSLT к файлу XML. Чтобы ускорить процесс, попробуйте скомпилировать XSLT, например, с помощью XSLTC.

person Sjoerd    schedule 02.05.2011
comment
Хотя я получаю разные XSLT почти при каждом вызове? - person Ivan; 02.05.2011

Я могу думать только о паре незначительных вещей:

  • TransformerFactory можно использовать повторно.

  • Transformer можно использовать повторно, если он ограничен потоком, а ввод XSL каждый раз один и тот же.

  • Если вы можете достаточно точно оценить выходной размер, вы можете создать ByteArrayOutputStream с подсказкой начального размера.

person Stephen C    schedule 02.05.2011

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

person Eric    schedule 02.05.2011