Убедительная просьба — не обвинять меня в незнании основных принципов Явы. Я в Яве новичок, но настолько я ее принципы понимаю.
Есть класс (public и прочее опустил)
class A {
A1 a1;
A2 a2;
// ...
}
В свою очередь
class A1 {
A11 a11;
A12 a12;
// ...
}
и т.д.. В общем, нормальная иерархия.
Проблема в том, что мне надо обеспечить максимальное быстродействие. Сейчас, когда надо, создаются экземпляры
A a = new A();
потом где-то (м.б., в конструкторе, м.б. нет)
a.a1 = new A1(); // или this.a1 = new A1();
a.a1.a11 = new A11();
и т.д. В общем, дергаем менеджер кучи для всех подобъектов, как и положено.
Между тем во всех этих классах в конечном счете есть только числа и текстовые строки. Массивов (не текстовых) нет, классов Явы тоже нет. Для текстовых строк я могу задать максимальный размер, ответственность за переполнение его беру на себя.
В С++ я бы описал все это одним пакетом
// описания A11,A12
class A1 {
A11 a11;
A12 a12;
// ...
};
class A {
A1 a1;
A2 a2;
// ...
};
и вызовом
A a = new A();
создал бы и сам A, и A1 и A11 и т.д. Там в экземпляре сидят экземпляры, а не ссылки.
Мне надо обеспечить максимальное быстродействие. И я хотел бы от этих вложенных new (и последующего освобождения этих блоков GC) избавиться
Понимаю, что такое вряд ли возможно, и все же — может, есть какие-то идеи ?
P.S. Уничтожить всю иерархию и запихать все на свете в один класс — не предлагать
Здравствуйте, Курилка, Вы писали:
К>Здравствуйте, Pavel Dvorkin, Вы писали:
К>[cut]
К>А насколько глубокая и широкая иерархия?
Уровней 5-10. Есть наследование, но полиморфизма нет. То есть реально если в классе должен быть Derived, то там и будет Derived, а не Base. В другом классе может быть Base, абстрактных классов вроде нет.
К>И насколько долго создаются объекты?
А кто их знает ? Не мерял. Само заполнение объектов примитивно просто, this.intval = intval и т.п. Могу лишь сказать, что в С++ заполнение полей заняло бы очень малое время по сравнению с временем new.
Да и не только создание меня беспокоит, но и освобождение тоже. А как померить, сколько времени GC понадобится на освобождение именно этих объектов — понятия не имею.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Убедительная просьба — не обвинять меня в незнании основных принципов Явы. Я в Яве новичок, но настолько я ее принципы понимаю. PD>Мне надо обеспечить максимальное быстродействие. И я хотел бы от этих вложенных new (и последующего освобождения этих блоков GC) избавиться PD>Понимаю, что такое вряд ли возможно, и все же — может, есть какие-то идеи ? PD>P.S. Уничтожить всю иерархию и запихать все на свете в один класс — не предлагать
Микроменеджмент и превентивная оптимизация.
В каком месте хочется оптимальной производительности? Создании объектов? GC? Доступа к данным в иерархии?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Убедительная просьба — не обвинять меня в незнании основных принципов Явы. Я в Яве новичок, но настолько я ее принципы понимаю.
PD>Есть класс (public и прочее опустил)
PD>...
PD>Между тем во всех этих классах в конечном счете есть только числа и текстовые строки. Массивов (не текстовых) нет, классов Явы тоже нет. Для текстовых строк я могу задать максимальный размер, ответственность за переполнение его беру на себя.
PD>В С++ я бы описал все это одним пакетом
PD>...
PD>и вызовом
PD>A a = new A();
PD>создал бы и сам A, и A1 и A11 и т.д. Там в экземпляре сидят экземпляры, а не ссылки.
PD>Мне надо обеспечить максимальное быстродействие. И я хотел бы от этих вложенных new (и последующего освобождения этих блоков GC) избавиться
Это невозможно по текущему стандарту джавы. Язык программирования джава, в оличие от с++, не дает возможность явно указывать способ работы с памятью — размещать на стеке/на куче, передавать ссылку/указатель/по значению. Максимум, на что можешь рассчитывать (пока) — escape analysis, появившийся в шестерке.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Да и не только создание меня беспокоит, но и освобождение тоже. А как померить, сколько времени GC понадобится на освобождение именно этих объектов — понятия не имею.
Если эти объекты не попадут в старое поколение, то нисколько не потратит. Да и на создание потратит немногим больше чем на выделение на стеке в C++. Конечно у тебя может долго отрабатывать создание объекта. Но от этого ты нигде не уйдешь. Если есть где то долговыполняемый код, то он должен где то выполниться.
Здравствуйте, Blazkowicz, Вы писали:
B>В каком месте хочется оптимальной производительности? Создании объектов?
Да.
>GC?
Да.
>Доступа к данным в иерархии?
Нет. Не актуально. Там нет массовых операций (кроме работы со строками).
В общем, сказать по правде, вся эта классовая иерархия по сути никакая не классовая иерархия, а просто вложенные структуры языка С (даже не C++) плюс конструкторы и методы, которые, в общем, тоже не очень нужны, вполне сойдет даже прямое обращение к полям (не надо меня ругать . И на размещение этой структуры (и удаление ее) я хочу потратить минимально возможное время. В С++ я мог бы вообще нулевое время потратить
Здравствуйте, Nicht, Вы писали:
N>Если эти объекты не попадут в старое поколение, то нисколько не потратит. Да и на создание потратит немногим больше чем на выделение на стеке в C++.
Вот это поясни. В С++ при выделении на стеке одна машинная команда нужна. На освобождение тоже — ret N
>Конечно у тебя может долго отрабатывать создание объекта.
Да нет, как только он размещен — считай, что уже создан. Там потом просто поля занести, в основном типа int.
Здравствуйте, Pavel Dvorkin, Вы писали:
N>>Если эти объекты не попадут в старое поколение, то нисколько не потратит. Да и на создание потратит немногим больше чем на выделение на стеке в C++. PD>Вот это поясни. В С++ при выделении на стеке одна машинная команда нужна. На освобождение тоже — ret N http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, Nicht, Вы писали:
N>>Если эти объекты не попадут в старое поколение, то нисколько не потратит. Да и на создание потратит немногим больше чем на выделение на стеке в C++.
PD>Вот это поясни. В С++ при выделении на стеке одна машинная команда нужна. На освобождение тоже — ret N
В новом поколении используется копирующий сборщик мусора. Это дает, то что куча всегда дефрагментирована. То есть выделение памяти происходит путем сдвига указателя. На сколько я знаю это операция пшиковая. При сборке, копирующий сборщик мусора вообще не смотрит на обекты которые не "используются". Тоесть твои обекты освободятся просты затеранием. Про них просто никто не будет знать.
>>Конечно у тебя может долго отрабатывать создание объекта.
PD>Да нет, как только он размещен — считай, что уже создан. Там потом просто поля занести, в основном типа int.
Здравствуйте, Pavel Dvorkin, Вы писали:
N>>Если эти объекты не попадут в старое поколение, то нисколько не потратит. Да и на создание потратит немногим больше чем на выделение на стеке в C++. PD>Вот это поясни. В С++ при выделении на стеке одна машинная команда нужна. На освобождение тоже — ret N
В Java — две инструкции Создание нового объекта — это буквально простое увеличение значения указателя на последнее свободное место.
Это возможно благодаря тому, что куча молодых объектов всегда дефрагментирована и каждый поток имеет в ней свою "арену". Во время сборки мусора из молодой кучи — все объекты будут упакованы и дефрагментированы. А после того, как объект переживет N циклов сборок — его продвинут (tenure) в "старую" кучу (на которой уже другие алгоритмы работают).
Так что создание динамического объекта в Java намного дешевле, чем в С++. Ну и еще escape analysis поможет.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А кто их знает ? Не мерял.
Тогда, собственно говоря, непонятно, о чем вообще тема: паранойя?
Или все ж таки почитать про GC, или забить мысли об оптимизации в дальний угол. Кстати, первый вариант приведет к практически (не все 100, но все же) такому же результату. Да и... насколько понял, программа еще не работает, но муки-потуги к оптимизации уже мучают. Странно это все...
Достаточно квалифицированный программист вряд ли напишет очень неэффективный код. По крайней мере, неосознанно. Оптимизация – это то, чем вы занимаетесь, когда текущая производительность вас не устраивает. Иногда оптимизировать легко, иногда сложно. Иногда оптимизация является частью оригинального дизайна, иногда приходится попирать все ваши красивые абстракции, заложенные в классовой иерархии. Но всегда, я повторюсь, всегда мой опыт показывал, что не сыскать программиста, который был бы способен предсказать или проанализировать узкие места в производительности без всякой информации. Не имеет значения, что вы думаете, будто знаете, где проблемы с производительностью. Вы будете весьма удивлены, узнав, что они спрятаны в совсем другом месте.
...
Оптимизация имеет смысл только тогда, когда она имеет смысл. И если это происходит, то смысл оптимизации действительно значим; но не увлекайтесь ею чрезмерно. Даже если вы знаете что есть смысл в оптимизации, сначала найдите, где есть место в коде для применения оптимизации. Без дополнительной информации о производительности вы не будете точно знать, что оптимизировать, поэтому все ваши усилия могут быть направлены не в то русло. В результате вы получите невразумительный код, который нельзя ни поддерживать, ни сопровождать, ни отлаживать, и который к тому же не решает ваших проблем. Такие последствия выражаются, во-первых, в увеличении стоимости разработки и сопровождения кода, а во-вторых, в отсутствии всякого реального улучшения производительности.
Здравствуйте, rsn81, Вы писали:
R>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>А кто их знает ? Не мерял. R>Тогда, собственно говоря, непонятно, о чем вообще тема: паранойя?
Нет. Надо ускорить работу. И все. Вот такая задача. И счет идет на миллисекунды.
R>Или все ж таки почитать про GC, или забить мысли об оптимизации в дальний угол. Кстати, первый вариант приведет к практически (не все 100, но все же) такому же результату. Да и... насколько понял, программа еще не работает, но муки-потуги к оптимизации уже мучают.
Не надо фантазировать, не зная ситуации. Есть данные, получаемые от "устройства" и передаваемые на другое "устройство" (что такое устройство — не суть важно). Их надо конвертировать в XML и обратно, такие сейчас требования, черт бы их побрал (требования) — для того, чтобы всякие 3d party могли сюда пристроиться, если захотят. Ни тому, ни другому устройству XML вообще-то не нужен. Но — придется преобразовывать в XML на входе и обратно на выходе. Все это чистые накладные расходы, и их надо свести к минимуму. А устройства и без того загружают процессор на 100%. А время там жестко лимитировано, не уложился sample — сняли его и минус добавили. Вот и все.
>Странно это все...
Java != C++ по такоум количеству параметров, что пытаться применять те же принципы и там, и там, надеясь на аналогичный результат — крайне неразумно. В свое время приводил стандартные девиации C++-программистов на управляемых платформах: Re[3]: Что стоит поучить?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>А кто их знает ? Не мерял. R>>Тогда, собственно говоря, непонятно, о чем вообще тема: паранойя? PD>Нет. Надо ускорить работу. И все. Вот такая задача. И счет идет на миллисекунды.
Бери профилятор и смотри где там у тебя bottleneck'и. Потом можно заняться тюнингом GC.
PD>Не надо фантазировать, не зная ситуации. Есть данные, получаемые от "устройства" и передаваемые на другое "устройство" (что такое устройство — не суть важно). Их надо конвертировать в XML и обратно, такие сейчас требования, черт бы их побрал (требования) — для того, чтобы всякие 3d party могли сюда пристроиться, если захотят. Ни тому, ни другому устройству XML вообще-то не нужен. Но — придется преобразовывать в XML на входе и обратно на выходе. Все это чистые накладные расходы, и их надо свести к минимуму. А устройства и без того загружают процессор на 100%. А время там жестко лимитировано, не уложился sample — сняли его и минус добавили. Вот и все.
Думай тогда как оптимизировать работу с XML — это будет самая тормозная часть.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>И счет идет на миллисекунды. PD>Их надо конвертировать в XML и обратно
Наличие такой комбинации вызывает улыбку и полное непонимание зачем при таком ударе по производительности в целом приходится тюнить такие мелочи как создание объектов и GC?
Почему такого в Java нет, и что есть объяснили выше. Добавлю что эмуляцию некоторых аспектов поведения структур если она очень нужна (например для интеграции с чем-то) можно сделать с помощью JNI. См. здесь.
PD>Не надо фантазировать, не зная ситуации. Есть данные, получаемые от "устройства" и передаваемые на другое "устройство" (что такое устройство — не суть важно). Их надо конвертировать в XML и обратно, такие сейчас требования, черт бы их побрал (требования) — для того, чтобы всякие 3d party могли сюда пристроиться, если захотят. Ни тому, ни другому устройству XML вообще-то не нужен. Но — придется преобразовывать в XML на входе и обратно на выходе. Все это чистые накладные расходы, и их надо свести к минимуму. А устройства и без того загружают процессор на 100%. А время там жестко лимитировано, не уложился sample — сняли его и минус добавили. Вот и все.
Почему-то кажется, что оптимизация создания объектов здесь ну очень-очень мало даст. Все-таки это легкая операция, абсолютно несравнимая с обработкой строк.
Новости очень смешные. Зря вы не смотрите. Как будто за наркоманами подсматриваешь. Только тетка с погодой в завязке.
There is no such thing as a winnable war.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Нет. Надо ускорить работу. И все. Вот такая задача. И счет идет на миллисекунды.
OK, просто конкретики в первом сообщении не было.
PD>Не надо фантазировать, не зная ситуации. Есть данные, получаемые от "устройства" и передаваемые на другое "устройство" (что такое устройство — не суть важно). Их надо конвертировать в XML и обратно, такие сейчас требования, черт бы их побрал (требования) — для того, чтобы всякие 3d party могли сюда пристроиться, если захотят. Ни тому, ни другому устройству XML вообще-то не нужен. Но — придется преобразовывать в XML на входе и обратно на выходе. Все это чистые накладные расходы, и их надо свести к минимуму. А устройства и без того загружают процессор на 100%. А время там жестко лимитировано, не уложился sample — сняли его и минус добавили. Вот и все.
Ну вот. Почему бы в первом сообщении не написать было все это? А то столько разговоров про оптимизацию аллокации, а все банальнее оказалось...
PD>И ничего странного, как видишь, нет.
Вижу, что есть. Выше вам уже сказали, что именно.
PD>Читал не один год назад. И сам высказвался на эту тему. PD>http://www.rsdn.ru/Forum/?mid=1419711
Угу, много истории: интересно, читая вспомнил, как давал своим студентам лабораторную, как вы выразились, по "самоубиванию программы", только у нас на кафедре как-то народ называл все "самопоеданием программы", но... честно говоря, к управляемым платформам (в частности, технологиям управления памятью GC и динамической компиляции JIT) отношения особенного не заметил.
Да и потом за "не один год" (вроде бы 2) многое изменилось. Мне вот иногда говорят: "Java самая тормозная!" — и тычут в результаты тестов, описанных в статье серии Кто сегодня самый шустрый
. Предлагаю им посмотреть на дату статьи (или версию тестируемого HostSpot): "сегодня" в названии — это уже сильно "вчера". Самое ужасное, что статьи "Технологии Клиент-Сервер" на этом сайте отображаются без дат, только мелко-мелко на обложке видно. А ведь читатель не всегда задумывается, что статья, быть может, описывает уже неактуальное состояние дел — так и рождаются мифы и легенды.
Бывает, начитавшись подобных статей подобно inline люди начинают фанатично расставлять модификаторы final на все методы подряд, ощущая радость мнимого улучшения производительности. И т.п. девиации от незнания.
Здравствуйте, Pavel Dvorkin, Вы писали:
К>>И насколько долго создаются объекты?
PD>А кто их знает ? Не мерял. Само заполнение объектов примитивно просто, this.intval = intval и т.п. Могу лишь сказать, что в С++ заполнение полей заняло бы очень малое время по сравнению с временем new.
PD>Да и не только создание меня беспокоит, но и освобождение тоже. А как померить, сколько времени GC понадобится на освобождение именно этих объектов — понятия не имею.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>И счет идет на миллисекунды. PD>>Их надо конвертировать в XML и обратно B>Наличие такой комбинации вызывает улыбку и полное непонимание зачем при таком ударе по производительности в целом приходится тюнить такие мелочи как создание объектов и GC?
Еще раз объясняю. Есть некий работающий продукт. В него надо встроить XML преобразование, о котором я писал. Оно отнимет время, в результате чего качество будет ухудшено (так как собственно обработка получит меньше времени, а там лимит по времени), и объяснить заказчику, почему мы начали улучшение продукта с потери качества, не очень-то легко. Поэтому это время надо свести к минимуму. Да, это время несравнимо с временем собственно обработки, намного меньше, но это несущественно.
О каком ударе по производительности ты говоришь — не понял.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
C>Бери профилятор и смотри где там у тебя bottleneck'и.
А что толку ? Там сейчас Xerces SAX стоит, не буду же я его переписывать!
C>Думай тогда как оптимизировать работу с XML — это будет самая тормозная часть.
А вот здесь был бы благодарен за любые советы. SAX можно и убрать, но на что заменить, чтобы было быстрее ? JAXB/JiXB будет быстрее или наоборот ?
В общем, суть задачи предельно проста. Есть XML, заведомо валидный, проверка не требуется. Есть XSD, описывающий его схему, тоже валидный. Необходимо из XML создать экземпляр класса Java и обратно. И как можно быстрее.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>О каком ударе по производительности ты говоришь — не понял.
У тебя будут основные тормоза на разборе XML. Да еще ты вроде бы начал JAXB использовать.
Если нужна скорость — используй быстрый парсер XML (лучше SAX или pull-парсер) и делай оптимизированый ручной mapping.
На фоне этого у тебя экономия на создании объектов даже измерима не будет.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>О каком ударе по производительности ты говоришь — не понял. C>У тебя будут основные тормоза на разборе XML. Да еще ты вроде бы начал JAXB использовать.
Еще не начал. Не стоит пробовать ?
C>Если нужна скорость — используй быстрый парсер XML (лучше SAX или pull-парсер) и делай оптимизированый ручной mapping.
Так сейчас и делается. Xerces SAX и ручная разборка. Про pull-парсеры не в курсе, если можешь, дай линк.
C>На фоне этого у тебя экономия на создании объектов даже измерима не будет.
Я, как тот утопающий, хватаюсь за любую соломинку. Меня тут упорно убеждали, что выделение памяти в Яве несравнимо по времени с, например, обработкой строк. Я в теории вполне согласен с этим, может, это и верно, но...
Сделал я следующий тест. В SAX заменил реальный content handler на пустой handler. Иными словами, SAX все делает как обычно, разбирает XML, парсит текст, вызывает у меня startDocument и прочее, только я в ответ никакие экземпляры не создаю и поля не заношу (а там, напоминаю, один числа и текстовые строки в конце концов). Так вот, время составляет примерно 50% от настоящего. Иными словами, 50% времени уходит на создание объектов (а может, на уничтожение потом ?) и присваивание значений полям.
И еще одно я сделал. Нашел некий SAX piccolo (http://piccolo.sourceforge.net/), который, как там утверждается, быстрее Xerces. Попробовал его. В среднем быстрее, но на некоторых образцах раза в 3-4 медленнее, причем нестабильно : пропускаю тесты один раз — медленнее, еще раз — нормально. Из-за чего ? Я могу отнести это только на какие-то проблемы с выделением/освобождением памяти, поскольку все остальное без изменений.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>О каком ударе по производительности ты говоришь — не понял. C>>У тебя будут основные тормоза на разборе XML. Да еще ты вроде бы начал JAXB использовать. PD>Еще не начал. Не стоит пробовать ?
Стоит. Попробуй и посмотри какое замедление будет. Еще на XML Binding из http://javolution.org/ можно посмотреть.
C>>Если нужна скорость — используй быстрый парсер XML (лучше SAX или pull-парсер) и делай оптимизированый ручной mapping. PD>Так сейчас и делается. Xerces SAX и ручная разборка. Про pull-парсеры не в курсе, если можешь, дай линк.
Xerces известен как достаточно большой тормоз, так что может иметь смысл взять альтернативный парсер.
Про pull-парсер — поищи по слову StAX.
PD>Сделал я следующий тест. В SAX заменил реальный content handler на пустой handler. Иными словами, SAX все делает как обычно, разбирает XML, парсит текст, вызывает у меня startDocument и прочее, только я в ответ никакие экземпляры не создаю и поля не заношу (а там, напоминаю, один числа и текстовые строки в конце концов). Так вот, время составляет примерно 50% от настоящего. Иными словами, 50% времени уходит на создание объектов (а может, на уничтожение потом ?) и присваивание значений полям.
Можно пример? Кстати, ты, надеюсь, HotSpot-компиляцию не считаешь?
PD>И еще одно я сделал. Нашел некий SAX piccolo (http://piccolo.sourceforge.net/), который, как там утверждается, быстрее Xerces. Попробовал его. В среднем быстрее, но на некоторых образцах раза в 3-4 медленнее, причем нестабильно : пропускаю тесты один раз — медленнее, еще раз — нормально.
Точно, HotSpot-компиляцию считаешь. Дело в том, что в Java байт-код транслируется в машинный код после того, как он будет работать в режиме интерпретации некоторое время. Порог компиляции зависит от опций JVM: серверная JVM имеет более высокий порог и использует большее количество оптимизаций (из-за чего программы под ней медленно запускаются, но потом работают быстрее), клиентская JVM имеет более низкий порог (т.е. она оптимизирована на более быстрый запуск).
На микротестах оно может дать очень существенный разброс. Например, мой сервер запускается за 3.5 секунды на клиентской JVM и более 6 секунд на серверной. Зато пропускная способность сервера на серверной JVM получается на 20% выше (из-за большего количества оптимизаций).
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>>О каком ударе по производительности ты говоришь — не понял. C>>>У тебя будут основные тормоза на разборе XML. Да еще ты вроде бы начал JAXB использовать. PD>>Еще не начал. Не стоит пробовать ? C>Стоит. Попробуй и посмотри какое замедление будет. Еще на XML Binding из http://javolution.org/ можно посмотреть.
Спасибо за ответ. Не буду
C>>>Если нужна скорость — используй быстрый парсер XML (лучше SAX или pull-парсер) и делай оптимизированый ручной mapping. PD>>Так сейчас и делается. Xerces SAX и ручная разборка. Про pull-парсеры не в курсе, если можешь, дай линк. C>Xerces известен как достаточно большой тормоз, так что может иметь смысл взять альтернативный парсер.
Можешь порекомендовать какой- то ?
C>Про pull-парсер — поищи по слову StAX.
OK, посмотрю.
PD>>Сделал я следующий тест. В SAX заменил реальный content handler на пустой handler. Иными словами, SAX все делает как обычно, разбирает XML, парсит текст, вызывает у меня startDocument и прочее, только я в ответ никакие экземпляры не создаю и поля не заношу (а там, напоминаю, один числа и текстовые строки в конце концов). Так вот, время составляет примерно 50% от настоящего. Иными словами, 50% времени уходит на создание объектов (а может, на уничтожение потом ?) и присваивание значений полям. C>Можно пример?
Увы, нельзя, код показать не могу. Могу показать только псевдо-хэндлер, но там решительно ничего нет, кроме вызова setContentHandler и переписанного parse.
>Кстати, ты, надеюсь, HotSpot-компиляцию не считаешь?
PD>>И еще одно я сделал. Нашел некий SAX piccolo (http://piccolo.sourceforge.net/), который, как там утверждается, быстрее Xerces. Попробовал его. В среднем быстрее, но на некоторых образцах раза в 3-4 медленнее, причем нестабильно : пропускаю тесты один раз — медленнее, еще раз — нормально. C>Точно, HotSpot-компиляцию считаешь. Дело в том, что в Java байт-код транслируется в машинный код после того, как он будет работать в режиме интерпретации некоторое время.
Из чего следует, что это здесь ни при чем. Дело в том, что пропускаю я набор из 200 тестов, и замедление (случайное) может быть на 100-м или 150-м, в общем, далеко не в начале набора. По логике вещей, там все уже откомпилировано к этому моменту.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Так сейчас и делается. Xerces SAX и ручная разборка. Про pull-парсеры не в курсе, если можешь, дай линк. C>>Xerces известен как достаточно большой тормоз, так что может иметь смысл взять альтернативный парсер. PD>Можешь порекомендовать какой- то ?
Если смотреть на это: http://www.xml.com/pub/a/2007/05/09/xml-parser-benchmarks-part-1.html , то http://woodstox.codehaus.org/ самый быстрый.
C>>Точно, HotSpot-компиляцию считаешь. Дело в том, что в Java байт-код транслируется в машинный код после того, как он будет работать в режиме интерпретации некоторое время. PD>Из чего следует, что это здесь ни при чем. Дело в том, что пропускаю я набор из 200 тестов, и замедление (случайное) может быть на 100-м или 150-м, в общем, далеко не в начале набора. По логике вещей, там все уже откомпилировано к этому моменту.
Вот как раз это больше всего ПОХОЖЕ на включение HotSpot'а. Каждый тест в отдельности будет запускаться в режиме интерпретации, а где-то в середине тестов включается компиляция какого-нибудь большого куска кода.
Если хочешь протестировать скорость правильно — выполни сначала каждый тест раз 1000 в цикле, а только потом измеряй сколько оно займет.
Здравствуйте, Cyberax, Вы писали:
C>Вот как раз это больше всего ПОХОЖЕ на включение HotSpot'а. Каждый тест в отдельности будет запускаться в режиме интерпретации, а где-то в середине тестов включается компиляция какого-нибудь большого куска кода.
Еще подумал — ты это можешь еще ловить полные циклы сборки GC (когда он собирает мусор в старом поколении). Тогда на время и положение паузы должны влиять опции GC (попробуй включать/выключать конкуррентный GC и покрутить настройки объема кучи).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>О каком ударе по производительности ты говоришь — не понял.
Исследование используемого XML движка и его оптимизация под проект могут дать, к примеру 1% выигрыша CPU, при том что какой-либо тюнинг в создании объектов не более чем 0.1%. Просто работы можно проделать достаточно много, придумывая хитроумные инициализации. Но при этом эффект будет пшиковый.
Здравствуйте, Cyberax, Вы писали:
C>Если нужна скорость — используй быстрый парсер XML (лучше SAX или pull-парсер) и делай оптимизированый ручной mapping.
Поидее прегенеренные сериализации вроде JAXB/JiBX должны быть быстрее.
Здравствуйте, Blazkowicz, Вы писали:
B>Исследование используемого XML движка и его оптимизация под проект могут дать, к примеру 1% выигрыша CPU, при том что какой-либо тюнинг в создании объектов не более чем 0.1%.
Хотелось бы верить...
>Просто работы можно проделать достаточно много, придумывая хитроумные инициализации. Но при этом эффект будет пшиковый.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Cyberax, Вы писали:
C>>Если нужна скорость — используй быстрый парсер XML (лучше SAX или pull-парсер) и делай оптимизированый ручной mapping. B>Поидее прегенеренные сериализации вроде JAXB/JiBX должны быть быстрее.
Разошлись вы тут с Cyberax во мнениях. Это вы, специалисты в Яве. Что же мне, дилетанту в ней, делать ?
Здравствуйте, Blazkowicz, Вы писали:
B> тюнинг в создании объектов не более чем 0.1%
Зато тюнинг GC может дать на много больше. Для начала советую включить опции "-XX:+PrintGCDetails -XX:+PrintGCTimeStamps". Или можно включить "-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime". Я не знаю какая норма отношения StoppedTime/ConcurrentTime, но если оно больше 5% то стопудово можно тюнить.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Разошлись вы тут с Cyberax во мнениях. Это вы, специалисты в Яве. Что же мне, дилетанту в ней, делать ?
А тебе взять, да померять оба варианта на своей иерархии. Работы на день максимум.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Зато тюнинг GC может дать на много больше. Для начала советую включить опции "-XX:+PrintGCDetails -XX:+PrintGCTimeStamps". Или можно включить "-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime". Я не знаю какая норма отношения StoppedTime/ConcurrentTime, но если оно больше 5% то стопудово можно тюнить.
Ну, о чем собственно уважаемому Павлу Дворкину и твердят с начала топике. Что оптимизации GC через параметры будет гораздо эффективней всяких выдумок на уровне кода.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Хотелось бы верить... PD>Может быть...
Вам одно и тоже повторило уже несколько человек, почему бы уже не прислушаться? Может эксперту в Java — Брайану Гетцу — поверите? Здесь Re[3]: хочу невозможного
давал две ссылки на его статьи именно про JIT-компиляцию в JVM и тщетные попытки оптимизации при ее наличии (там же можно найти статьи про GC и избыточность оптимизации аллокации/деаллокации в условии развитого GC).
Здравствуйте, Blazkowicz, Вы писали:
PD>>Разошлись вы тут с Cyberax во мнениях. Это вы, специалисты в Яве. Что же мне, дилетанту в ней, делать ? B>А тебе взять, да померять оба варианта на своей иерархии. Работы на день максимум.
JAXB работает поверх SAX. SAX-имплементацию можно менять, т.е. если известно, что A быстрее, чем B на тех данных, которые надо будет обрабатывать в приложении, то нужно подставить A (через endorsed или как там). JAXBу это будет прозрачно незаметно.
а вот ручной маппинг имхо следует писать только в том случае, если есть уверенность довести его до уровня гарантированного превышения скорости работы того же JAXB.
довести его за день — малореально
Здравствуйте, Blazkowicz, Вы писали:
B>А тебе взять, да померять оба варианта на своей иерархии. Работы на день максимум.
Ага. Только померить, как сказано выше уже несколько раз, то есть с учетом JIT-компиляции, а то он опять запустит по одному тесту или каждую итерацию теста в виде запуска новой виртуалки — и опять придет сюда говорить, что 50% выигрыша.
Здравствуйте, rsn81, Вы писали:
R>Ага. Только померить, как сказано выше уже несколько раз, то есть с учетом JIT-компиляции, а то он опять запустит по одному тесту или каждую итерацию теста в виде запуска новой виртуалки — и опять придет сюда говорить, что 50% выигрыша.
А нельзя ли прочитать внимательно, что я написал, прежде чем второй раз вольные фантазии городить ? Вот здесь, в конце.
Из чего следует, что это здесь ни при чем. Дело в том, что пропускаю я набор из 200 тестов, и замедление (случайное) может быть на 100-м или 150-м, в общем, далеко не в начале набора. По логике вещей, там все уже откомпилировано к этому моменту.
P.S. Вообще, если тебя раздражают мои вопросы — можно и не отвечать вообще. Я не флейма ради эту дискуссию затеял, мне реальный ответ нужен.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Разошлись вы тут с Cyberax во мнениях. Это вы, специалисты в Яве. Что же мне, дилетанту в ней, делать ? B>А тебе взять, да померять оба варианта на своей иерархии. Работы на день максимум.
Ох, не знаю. SAXB свои собственные классы создает, и мне, видимо, надо именно их использовать, так ? или нет ? "Ручная" реализация классов уже создана (не мной), используется в SAX Xerces, и там много чего еще понавешено, к делу не относящегося.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А нельзя ли прочитать внимательно, что я написал, прежде чем второй раз вольные фантазии городить ? Вот здесь, в конце. PD>http://www.rsdn.ru/forum/message/2723755.1.aspx
Очень внимательно прочитал и ждал описания конкретики тестов (см. ниже).
PD>На всякий случай повторяю
[skipped]
Вас там ниже Cyberax спросил, как именно вы запускаете тесты: пачка из N-тестов должна запускать в рамках одной виртуальной машины, а не каждый тест отдельно. Динамическая компиляция итеративный процесс выполняемый JIT-ом, который накапливает и использует для оптимизации информацию о вашей программе. Ждал с нетерпением ответа на тот вопрос, но увы, его не последовало.
Да и вообще, прочитав статьи Гетца, ссылки на которые давал вам выше, про тестирование производительности на управляемых платформах, начинаешь очень иронично относиться к любым таким попыткам... тем более людей, имеющих только опыт программирования на языках статической компиляции.
PD>P.S. Вообще, если тебя раздражают мои вопросы — можно и не отвечать вообще. Я не флейма ради эту дискуссию затеял, мне реальный ответ нужен.
Меня вовсе не раздражает, а несколько забавляет, как вам множество раз говорят одно и тоже, а вы упорно это игнорируете.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Andrei N.Sobchuck, Вы писали:
B>Ну, о чем собственно уважаемому Павлу Дворкину и твердят с начала топике. Что оптимизации GC через параметры будет гораздо эффективней всяких выдумок на уровне кода.
Уважаемый Павел Дворкин ничего против этого не имеет, но , насколько я понимаю, эта самая оптимизация коснется не только этой части (которая в конце концов есть только 1% от суммарного времени, если не меньше), но и всей системы в целом. И сейчас я просто не готов ни оценить все это, ни решить, насколько такое допустимо. А за совет спасибо.
Здравствуйте, rsn81, Вы писали:
R>Вас там ниже Cyberax спросил, как именно вы запускаете тесты: пачка из N-тестов должна запускать в рамках одной виртуальной машины, а не каждый тест отдельно.
>Динамическая компиляция итеративный процесс выполняемый JIT-ом, который накапливает и использует для оптимизации информацию о вашей программе. Ждал с нетерпением ответа на тот вопрос, но увы, его не последовало.
for (Integer test = 1; test <= 200; test++) {
file_name = "D:\\tester\\XMLData\\" + test.toString() ;
File in = new File(file_name);
test(in);
}
Достаточно на этот раз ясно или нет ?
R>Да и вообще, прочитав статьи Гетца, ссылки на которые давал вам выше, про тестирование производительности на управляемых платформах, начинаешь очень иронично относиться к любым таким попыткам... тем более людей, имеющих только опыт программирования на языках статической компиляции.
Ну если так, то ответь мне на вопрос, который я задал здесь. Предположение Cyberax о HotSpot, я полагаю, отметено, вот и ответь.
И еще одно я сделал. Нашел некий SAX piccolo (http://piccolo.sourceforge.net/), который, как там утверждается, быстрее Xerces. Попробовал его. В среднем быстрее, но на некоторых образцах раза в 3-4 медленнее, причем нестабильно : пропускаю тесты один раз — медленнее, еще раз — нормально. Из-за чего ? Я могу отнести это только на какие-то проблемы с выделением/освобождением памяти, поскольку все остальное без изменений.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Ну если так, то ответь мне на вопрос, который я задал здесь. Предположение Cyberax о HotSpot, я полагаю, отметено, вот и ответь.
А как со статистикой от GC?
Попробовал. В варианте собственно разбора (выдать список всех имен по механизму getNext()) работает примерно на 50% быстрее чем Xerces SAX с его callback. Любопытно и даже очень. Если это удастся прикрутить к иерархии классов без серьезных затрат времени, то будет просто замечательно. Большое спасибо.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Ну если так, то ответь мне на вопрос, который я задал здесь. Предположение Cyberax о HotSpot, я полагаю, отметено, вот и ответь. C>А как со статистикой от GC?
Пока никак. Незнаком я с этим в Яве. Если можно, ткни куда смотреть.
C>Ну и наконец: используй профайлер.
То же самое. Вот в Visual C++ 6.0 я на нем собаку съел (а в VS 7 они его, паразиты, убрали).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>Ну если так, то ответь мне на вопрос, который я задал здесь. Предположение Cyberax о HotSpot, я полагаю, отметено, вот и ответь. C>>А как со статистикой от GC? PD>Пока никак. Незнаком я с этим в Яве. Если можно, ткни куда смотреть.
Самое простое: http://rsdn.ru/Forum/Default.aspx?mid=2724014&flat=0
C>>Ну и наконец: используй профайлер. PD>То же самое. Вот в Visual C++ 6.0 я на нем собаку съел (а в VS 7 они его, паразиты, убрали).
Bottleneck'и, в принципе, почти все профиляторы нормально могут. Мне больше всего пока вот этот нравится: http://www.yourkit.com/
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Уважаемый Павел Дворкин ничего против этого не имеет, но , насколько я понимаю, эта самая оптимизация коснется не только этой части (которая в конце концов есть только 1% от суммарного времени, если не меньше), но и всей системы в целом. И сейчас я просто не готов ни оценить все это, ни решить, насколько такое допустимо. А за совет спасибо.
Это кстати паршиво, выходит конкретно тюнить GC под твое решение смысла нет. Остается только профайлить.
Здравствуйте, Cyberax, Вы писали:
C>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>>>Ну если так, то ответь мне на вопрос, который я задал здесь. Предположение Cyberax о HotSpot, я полагаю, отметено, вот и ответь. C>>>А как со статистикой от GC? PD>>Пока никак. Незнаком я с этим в Яве. Если можно, ткни куда смотреть. C>Самое простое: http://rsdn.ru/Forum/Default.aspx?mid=2724014&flat=0
Я тебе сегодня уже надоел со своими дилетантскими вопросами, но куда эти опции в Eclipse ставить и что с ними дальше делать ? Попробовал в VM settings — ничего не выдается вроде никуда
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Я тебе сегодня уже надоел со своими дилетантскими вопросами, но куда эти опции в Eclipse ставить и что с ними дальше делать ? Попробовал в VM settings — ничего не выдается вроде никуда
Зависит от используемой реализации JVM и её версии.
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Я тебе сегодня уже надоел со своими дилетантскими вопросами, но куда эти опции в Eclipse ставить и что с ними дальше делать ? Попробовал в VM settings — ничего не выдается вроде никуда
B>Зависит от используемой реализации JVM и её версии.
Вопрос снят. По крайней мере удалось в файл вывести
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Здравствуйте, Blazkowicz, Вы писали:
B>> тюнинг в создании объектов не более чем 0.1%
ANS>Зато тюнинг GC может дать на много больше. Для начала советую включить опции "-XX:+PrintGCDetails -XX:+PrintGCTimeStamps". Или можно включить "-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime". Я не знаю какая норма отношения StoppedTime/ConcurrentTime, но если оно больше 5% то стопудово можно тюнить.
Попробовал "-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime". Вот несколько строк
Application time: 0.0480905 seconds
0.106: [GC 511K->144K(1984K), 0.0035792 secs]
Total time for which application threads were stopped: 0.0038552 seconds
Application time: 0.0359529 seconds
0.145: [GC 656K->161K(1984K), 0.0019033 secs]
Total time for which application threads were stopped: 0.0021394 seconds
А вообще таких наборов строк штук 100. Почему, если не секрет ?
Соотношение , как видно, больше 5%, хоть и не сильно. Но оно примерно то же что у меня, что в примере от http://woodstox.codehaus.org/ я и его попробовал (со своим файлом).
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А вообще таких наборов строк штук 100. Почему, если не секрет ?
Это вполне нормально — собирается куча для новых объектов ("Эдем"). Она небольшая, поэтому сборка идет часто.
PD>Соотношение , как видно, больше 5%, хоть и не сильно. Но оно примерно то же что у меня, что в примере от http://woodstox.codehaus.org/ я и его попробовал (со своим файлом).
GC надо под конкретную задачу настраивать (на уже готовом приложении), причем микротесты часто ведут себя совсем по-другому, чем настоящее приложение.
Я бы лично пока дальше копал в направлении оптимизации работы с XML.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>А вообще таких наборов строк штук 100. Почему, если не секрет ?
Молодое поколение (new gen) собирается часто.
Попробуй теперь с "-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution" и давай эту инфу сюда. На основании TenuringDistribution можно увеличить/уменьшить молодое поколение. Скажу сразу, правил я не знаю, всё эмпирическим путём
PD>Соотношение , как видно, больше 5%, хоть и не сильно. Но оно примерно то же что у меня, что в примере от http://woodstox.codehaus.org/ я и его попробовал (со своим файлом).
Если машина многоголовая, то можно включить параллельный коллектор "-XX:+UseParallelGC".
Здравствуйте, Blazkowicz, Вы писали:
PD>>которая в конце концов есть только 1% от суммарного времени, если не меньше B>Это кстати паршиво, выходит конкретно тюнить GC под твое решение смысла нет. Остается только профайлить.
Здравствуйте, Cyberax, Вы писали:
C>Я бы лично пока дальше копал в направлении оптимизации работы с XML.
Если выгода от оптимизации работы с XML 30%, а от оптимизации GC от силы 2%, то вывод очевиден. В принципе согласен — на микротестах тюнить GC смысла нет.
предположение По факту всё может быть веселее.
Если ты перечитаешь весь топик, то поймешь, что Павел разрабатывает решение в рамках большого работающего проекта. Работающего в той же JVM. Так вот тюнить каким-то образом GC под решение Павла смысла вообще нет. Так как в совокупности с остальной системой нужен будет совершенно новый анализ и совсем другие настройки.
Здравствуйте, Andrei N.Sobchuck, Вы писали:
ANS>Попробуй теперь с "-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution" и давай эту инфу сюда. На основании TenuringDistribution можно увеличить/уменьшить молодое поколение. Скажу сразу, правил я не знаю, всё эмпирическим путём
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>В общем, суть задачи предельно проста. Есть XML, заведомо валидный, проверка не требуется. Есть XSD, описывающий его схему, тоже валидный. Необходимо из XML создать экземпляр класса Java и обратно. И как можно быстрее.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>В общем, суть задачи предельно проста. Есть XML, заведомо валидный, проверка не требуется. Есть XSD, описывающий его схему, тоже валидный. Необходимо из XML создать экземпляр класса Java и обратно. И как можно быстрее.
А>Тебе ссылку http://javolution.org/api/javolution/xml/package-summary.html#package_description я зачем давал? Ты даже не удосужился попробовать.
А ты сам ее пробовал ? Если да, объясни, что я не так делаю.
По ссылке есть пример. В примере используются классы, которые не описаны, так что я его непосредственно пропустить не мог. Сделал по образцу простенький тест
package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import javolution.xml.XMLBinding;
import javolution.xml.XMLFormat;
import javolution.xml.XMLObjectReader;
import javolution.xml.XMLObjectWriter;
import javolution.xml.XMLSerializable;
import javolution.xml.stream.XMLStreamException;
public class Graphic implements XMLSerializable {
static final long serialVersionUID = 1;
private String str;
public Graphic() {
str = "test";
}
// Default XML format with name associations (members identified by an unique name).
// See XMLFormat for examples of positional associations.
protected static final XMLFormat<Graphic> XML = new XMLFormat<Graphic>(Graphic.class) {
public void write(Graphic g, OutputElement xml) throws XMLStreamException {
xml.add(g.str, "str", String.class);
}
public void read(InputElement xml, Graphic g) throws XMLStreamException {
g.str = xml.get("str");
}
};
public static void main(String[] args) {
XMLBinding binding = new XMLBinding();
binding.setAlias(Graphic.class, "Graphic");
binding.setClassAttribute("type"); // Use "type" instead of "class" for class attribute.
// Writes the area to a file.
try {
Graphic g = new Graphic();
XMLObjectWriter writer = XMLObjectWriter.newInstance(new FileOutputStream("C:/area.xml"));
writer.setBinding(binding); // Optional.
writer.setIndentation("\t"); // Optional (use tabulation for indentation).
writer.write(g, "Graphic", Graphic.class);
writer.close();
// Reads the area back
XMLObjectReader reader = XMLObjectReader.newInstance(new FileInputStream("C:/area.xml"));
reader.setBinding(binding);
Graphic g1 = reader.read("Graphic", Graphic.class);
System.out.println(g1.str);
reader.close();
}
catch (XMLStreamException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {}
}
}
Писать — пишет, при чтении выдает
javolution.xml.stream.XMLStreamException: Cannot retrieve class (class attribute not found)
at javolution.xml.XMLBinding.readClassAttribute(Unknown Source)
at javolution.xml.XMLFormat$InputElement.get(Unknown Source)
at test.Graphic$1.read(Graphic.java:28)
at test.Graphic$1.read(Graphic.java:1)
at javolution.xml.XMLFormat$InputElement.get(Unknown Source)
at javolution.xml.XMLFormat$InputElement.get(Unknown Source)
at javolution.xml.XMLObjectReader.read(Unknown Source)
at test.Graphic.main(Graphic.java:48)