LINUX.ORG.RU

[java] Бить ли за new по рукам?

 


0

0

Иначе говоря, в стандартных в том числе библиотеках, на каждый пук создается по туче объектов, как событий, так и толпы копий не иммутабельных классов а-ля Point и т.п. Вот и интересно мне насколько сильный от всего этого безобразия оверхед, и что делать.

★★☆

Оверхед скорее по памяти чем по производительности. На лично опыте знаю что при кеширование Integer - проверка на существование занимает дольше чем выделение.

А вообще - нужно наконец усадить жабовоятелей написать нормальный риджин инференс.

theos ★★★
()

за пук бить длинной металической линейкой по рукам и попе
потом проветрить

yltsrc
()

большой.

а ещё круче какой-нибудь метод типа method(Integer i); или просто использование Integer (и прочих иммутабельных объектов), где ни попади, в итоге из-за кучи боксинга/анбоксинга можно получить забавный оверхед.

qnikst ★★★★★
()
Ответ на: комментарий от theos

и да, если это разовое явление, то нужно тыкнуть носом
а если over9000, то убивать на месте, т.к. все относительно

yltsrc
()
Ответ на: комментарий от theos

Дык можно не кешировать, а например возвращать point, с package visible методами для изменения, там полно путей для изврата, вопрос надо ли.

wfrr ★★☆
() автор топика
Ответ на: комментарий от theos

риджин инференс

Ять, вы либо перевод пишите, либо латиницей. А то прямо мандалай какойто.

wfrr ★★☆
() автор топика
Ответ на: комментарий от qnikst

Иммутабельные объекты зато не надо копийровать. Ато есть маразмы а-ля:

http://www.docjar.com/html/api/java/io/ByteArrayOutputStream.java.html#141 - каково, а? Т.е. пишем в приватный буфер мегабайт данных, а паранойидальные разработчики берут его и тупо копируют.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

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

anonymous
()

Взять и помотреть?

Как отправная точка:

# dtrace -qn 'hotspot*:::object-alloc { printf("new %s\n", stringof(copyin(arg1, arg2))); }'
anonymous
()
Ответ на: комментарий от wfrr

дык палка то о двух концах. Или приходится копировать кучу данных при mutable объектах или плодить кучу immutable объектов (при их изменении), тут же отдавая старые gc.

с приведённым кодом - согласен, что маразм чистой воды.

qnikst ★★★★★
()
Ответ на: комментарий от anonymous

оно тормозить будет от вывода этой строки гораздо больше, а так в IDE встроены профилировщики, кои показывают кол-во объектов, но толку.

wfrr ★★☆
() автор топика
Ответ на: комментарий от qnikst

Дык, яж писал, можно выдавать клиенту иммутабельный интерфейс, и всего то. Таки образом ничего копировать ненужно, да и тотже Point запрашивать 10 раз не придется, но наверняка тут свои косяки есть.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

> но тормозить будет от вывода этой строки гораздо больше, а так в IDE встроены профилировщики, кои показывают кол-во объектов, но толку.

Ну так это ж для затравки. Строку выводить на каждый чих никто не заставляет. Можно накапливать статистику и выводить периодически. Ну если данных профилировщика хватает - вот и славно.

anonymous
()
Ответ на: комментарий от wfrr

ну косяки immutable появляются сразу же когда мы из изменяем. хотя бы ставящее в ступор тех кто не читает спеки String s=new String();for (i ...) { s+=«что-нибудь}

и подобное может вылезать много где, создали новый объект старый забыли и опять...

извиняюсь если К.О.-шничаю..

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Что йто вы меня не читаете.

public interface Point{
  int getX();
  int getY()
}

class PointImpl implements Point{
  int x;
  int y;
  //далее тупо геттеры для реализации интерфейса
}

// код в другом пакете:

Point p = someObj.getPoint(); 
// тут возвращается иммутабельный интерфейс, 
// но объект то не иммутабельный, т.е. ни копировать ни создавать 
// ничего не надо
p.getX()
wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

ок.

В случае приведённом в тупокоде у нас гарантируется изоляция скопированного себе кода от поданного. Если я правильно понимаю, то в данном случае изоляции нету есть изоляция только в одну сторону, т.е. если someObj или кто-то ещё может менять значение того, на что указывает p (т.е. p.getX() может вернуть уже что-то другое), то у нас будет всё плохо. Если данных требований перед системой нет, то да, это хорошее решение.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

под тупокодом имеется ввиду ссылка на либу, где копируется большой массив.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Если я правильно понимаю, то в данном случае изоляции нету есть изоляция только в одну сторону, т.е. если someObj или кто-то ещё может менять значение того, на что указывает p (т.е. p.getX() может вернуть уже что-то другое), то у нас будет всё плохо. Если данных требований перед системой нет, то да, это хорошее решение.

Да, причем в некоторых случаях, например с координатами часто нужно знать _ктуальные_ координаты, т.е. в обычном подходе придется их итеративно перезапрашивать, кроме того при работе в AWTThread есть призрачная гарантия что они не поменяются.

wfrr ★★☆
() автор топика
Ответ на: комментарий от wfrr

>Дык можно не кешировать

Да я не об этом. Я про то, что new в джаве офигенно быстрый.

А то что я называл - region inference. Мне казалось wlor уже всем раструбил про него =)

theos ★★★
()
Ответ на: комментарий от theos

Мне казалось wlor уже всем раструбил про него =)

Я его практически не читаю, он ударен своими теоретическим задроствами, а реальный мир суров и на кодо-онанизм времени не дает.

wfrr ★★☆
() автор топика

Я вот вчера глянул в исходники одной вроде простой программки для Андроид (на java), так там вся программа размазана по десяткам вложенных друг в друга каталогов. Так что, все жаба-кодеры делают, чтобы это выглядело запутанно и непонятно, или это только на Андроиде такая мода? //код там вообще мне показался ужасен, но это отдельный разговор.

Dimanc ★★
()
Ответ на: комментарий от Dimanc

Вам, таки, стоит прочитать про яву немного, хотябы для того чтобы на ней никогда больше не писать.

wfrr ★★☆
() автор топика

После того, как за полтора месяца был написан AWT, в мае 1995 года вышла Java 1.0 и началась эра быдлокодерства для Web. Абсолютно все разработчики были настолько увлечены идеями ООП, что даже спустя 15 лет приходится иметь дело с таким говном ради обратной совместимости.

iZEN ★★★★★
()
Ответ на: комментарий от wfrr

Смотри сам. SWT проектировали, опираясь на опыт AWT и Swing. Кент Бек, один из разработчиков SWT, принимал активное участие в разработке архитектуры Eclipse.

iZEN ★★★★★
()
Ответ на: комментарий от iZEN

>Смотри сам. SWT проектировали, опираясь на опыт AWT и Swing.

К сожалению SWT - это загиб в противополжном напрвлении. Без JFace вообще не юзабелен. Да и с ним тяжко.

theos ★★★
()
Ответ на: комментарий от wfrr

>Вам, таки, стоит прочитать про яву немного, хотябы для того чтобы на ней никогда больше не писать.

Белк, ты мне так и не ответил на вопрос.

Dimanc ★★
()
Ответ на: комментарий от wfrr

> он ударен своими теоретическим задроствами

Пока весь мир «просто использует» наработки, кто-то должен двигать технологии вперед ;)

theos ★★★
()

Оверхед очень маленький. Выделение памяти в джаве очень быстрое, короткоживущие объекты собираются generational GC тоже очень быстро. Вряд ли это может стать причиной плохой производительности.

Вот копирование мегабайтов это дикость, тут видимо просто надо на каждый подозрительный случай проверять исходники JDK.

Legioner ★★★★★
()
Ответ на: комментарий от wfrr

Там про всё буквально. В этой тоненькой книжечке вся суть, по сравнению с которой Стив Макконнелл — просто вода.

iZEN ★★★★★
()

Это Ынтерпрайз, детка. Привыкай. Там нормально для калькулятора создавать овер 9к объектов и жрать ресурсы гигабайтами.

tia
()
Ответ на: комментарий от iZEN

что меня всегда удивляло - т.к. это люди прочитавшие кучу книг, которые постоянно ссылаются на кого-то, употребляют «умные» слова, а на практике ничего не умеют и делают детские и глупые ошибки

lester ★★★★
()
Ответ на: комментарий от Legioner

> Выделение памяти в джаве очень быстрое, короткоживущие объекты собираются generational GC тоже очень быстро

Но все же медленнее, чем просто сдвигом SP (1 инструкция vs. до хера, где до хера = O(размер первого поколения)). Так что region analysis рулил бы, если бы его они осилили.

anonymous
()
Ответ на: комментарий от Legioner

> Выделение памяти в джаве очень быстрое,

тут да, всё понятно.

короткоживущие объекты собираются generational GC тоже очень быстро.

а тут обоснование будет?

qnikst ★★★★★
()
Ответ на: комментарий от Legioner

Вот в жизни не поверю, что плодящиеся и тут же становящиеся ненужными объекты не будут сильно тормозить программу. Даже учитывая все оптимизации сделанные в gc на сегодняшний момент, хотя может быть потомк, что описание слишком поверхностное, оно не выглядит хорошим обоснованием. Ну да ладно, может и правда.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Ну вот набросал небольшой синтетический тестик: http://pastebin.com/WHiRrBHk

если закомментить строчки с a и раскомментить строчки с b, то цикл не будет создавать объекты, иначе в каждой итерации создаётся объект класса Integer.

Скорость с созданием объекта у меня примерно 87032201 (т.е. 87 миллионов объектов в секунду). Скорость без создания объекта у меня примерно 204081632, т.е. примерно в 2.5 раза больше.

Мне немножко лень писать этот тест на С++, но я думаю, С++ здесь отстанет от Java, если в каждой итерации создавать объект в динамической памяти и удалять предыдущий.

Legioner ★★★★★
()
Ответ на: комментарий от lester

Просто у таких людей нет постоянной практики и окончательно сформированной точки зрения на ту или иную проблему. И иногда изложения взглядов этих людей на ту или иную проблему понимают и принимают буквально как РУКОВОДСТВО_К_ДЕЙСТВИЮ, что глупо втройне. Нужно включать собственные мозги и вести ДИАЛОГ, приближаясь к подходящему в конкретном случае решению.

iZEN ★★★★★
()
Ответ на: комментарий от iZEN

> Нужно включать собственные мозги и вести ДИАЛОГ, приближаясь к подходящему в конкретном случае решению.

ты в задаче на три класса и 20 строк сделал неправильно ВСЕ - неправильно спроектировал самый базовый класс Resizeable, сделал левое наследование, получил левый нерабочий метод в «квадрате», написал костыли, чтоб заткнуть кривизну, кидаешь абсолютно нелогичное исключение в этом костыле, еще и по непосредственной реализации тебе указали на ошибки - какой тут «ДИАЛОГ»? что в данном случае обсуждать, если ничего дельного от тебя не было, кроме «умных» слов и ссылок на разных авторитетов?

lester ★★★★
()
Ответ на: комментарий от Legioner

> Мне немножко лень писать этот тест на С++, но я думаю, С++ здесь отстанет от Java

в С++ можно прямо указать в new, где будет «создан» объект - так что если говорить про постоянное удаление/создание, то С++ тут выиграет без вопросов, если создавать сразу много объектов - то опять же в С++ очень просто подключить пул памяти, и опять же С++ впереди с большим отрывом

lester ★★★★
()
Ответ на: комментарий от lester

в С++ можно прямо указать в new, где будет «создан» объект - так что если говорить про постоянное удаление/создание, то С++ тут выиграет без вопросов, если создавать сразу много объектов - то опять же в С++ очень просто подключить пул памяти, и опять же С++ впереди с большим отрывом

Про большой отрыв не уверен :)

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

> Про большой отрыв не уверен :)

ну в твоем примере для С++ вообще не будет аллокации памяти, только дергаться конструктор/деструктор, если есть, а если нет, как опять же в примере, - так вообще ничего будет происходить с включенной оптимизацией, а это явно быстрее чем вариант на Java :)

lester ★★★★
()
Ответ на: комментарий от Legioner

если же сравнивать с пулом - то тут не будет никаких мелких действий и дефрагментаций, одной командой просто «забываем» мусор, после отработки операции и все, да и выделение памяти будет по сути просто инкрементом указателя

lester ★★★★
()
Ответ на: комментарий от lester

неправильно спроектировал самый базовый класс Resizeable

Resizeable — это интерфейс, а не класс. Очнись, мы о Java говорим, а не о C++.

сделал левое наследование, получил левый нерабочий метод в «квадрате»

Код рабочий. С защитой от левых данных. Можешь сам проверить.

чтоб заткнуть кривизну

Это да. Я решил показать, что может делать с наследованием, кто с ним столкнётся. В AWT такой кривизны навалом.

абсолютно нелогичное исключение в этом костыле

Абсолютно логичное — исключение словит клиент там, где попытается использовать квадрат в качестве разностороннего прямоугольника.

и по непосредственной реализации тебе указали на ошибки

Кто указал? Ты что ли?

По-моему, весь примерный код по теме писали только я и qnikst, который высказывал хоть какие-то сомнения. Вот с ним диалог вести можно, с тобой — не, тут непробиваемая защита по типу «сам дурак».

что в данном случае обсуждать, если ничего дельного от тебя не было, кроме «умных» слов и ссылок на разных авторитетов?

Ты не привёл ни строчки правильного с твоей точки зрения кода, что вообще можно с тобой обсуждать?

iZEN ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.