Убедительная просьба — не обвинять меня в незнании основных принципов Явы. Я в Яве новичок, но настолько я ее принципы понимаю.
Есть класс (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 понадобится на освобождение именно этих объектов — понятия не имею.