Re[2]: macro и micro memory management. Java и С
От: c-smile Канада http://terrainformatica.com
Дата: 05.12.05 19:11
Оценка: 1 (1) :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, c-smile, Вы писали:


CS>>Вот такие вот мои мысли в слух если они кому интересны.


PD>Мысли интересны, но не кажется ли тебе, что это можно выразить короче ? А именно — для достаточно часто выполняемых коротких операций не надо дергать кучу , если это возможно и не противоречит высшим идеям При этом неважно, управляемая она или нет. Твой пример можно вполне на неуправляемый С++ перевести, и он там будет так же точно выглядеть, только явный вызов delete добавится. И эффекты будут те же — по скорости.


Вопрос на самом деле лежит в несколько иной плоскости:
Скажем грамотное (или оптимальное) использование memory managers.

Есть ситуации когда микроменеджмент выполняется в том числе с помощью new/delete (malloc/free) и само собой аллокацией на стеке. микроменеджмент памяти это ситуация когда мы знаем точно время жизни объекта.
Не использовать это знание — значит обрекать себя на неоптимальное решение.

И есть ситуации когда GC на высоте — заведомо лучше справляется с ситуацией или позволяет строить более надежную систему.

Имея опыт написания managed/unmanaged компонент на .NET(MC++) и Java(JNI) пришел к заключению
что модель native методов в Java (JNI) лучше. Во многих смыслах.

Macromangement памяти это удел таких систем как Java.
И это хорошо на самом деле что в ней нет всяких подпорок типа using.
Они там не нужны по большому счету.
RAII в С++ — он для этого то что надо. GC в Java — то что нужно.

Это я пытаюсь мыслить в слух в том числе на тему:
Все-в-одном как MC++ например это хорошо или плохо?
Что-то мне говорит что будет как всегда.
Re[6]: macro и micro memory management. Java и С
От: c-smile Канада http://terrainformatica.com
Дата: 06.12.05 01:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

CS>>В моем случае это

CS>>будет простой набор методов
CS>>Graphics.setGradientBrush(...) Это если оно надо.
S>А, то есть ты предлагаешь сделать в Graphics по методу на каждый конструктор одного из потомков кисти? Может быть, оно и оправдано. Хотя я не уверен: дело в том, насколько удобно это будет в применении. У тебя не будет возможности в одном месте решить, какой кистью закрашивать, а в другом — какую фигуру нарисовать. Так бы ты сделал метод DrawRectangle, принимающий параметры прямоугольника и кисть, которая взята откуда-то снаружи (из преференсов пользователя, к примеру). И он бы работал для всех кистей, независимо от того, в каком порядке что вызывалось. А при твоем способе нужно следить за тем, чтобы ненароком не испортить состояние Graphics лишним вызовом setXXX().
CS>>Полиморфизм вещь хорошая, но там где он нужен. Все — в меру. Как всегда.
S>Верно.

Если действительно нужен полиморфизм здесь то сделать себе поверх этого
class Brush и класс GraphicsEx: public Graphics не представляет проблемы.
Просто это далеко не всегда нужно.

В качесве примера: есть стиль (CSS) у которого в общем случае
четыре border и их brushes, background solid border (+ у меня еще и градиент)
background image brush в разных вариациях и т.д.
Хранить это все безобразие в виде отдельных объектов типа Brush, Color и пр....
Я думаю мысль понятна и продолжать её не надо.
Классовые иерархии вещь конечно хорошая. Если задача в них вмещается. Если же нет — все, труба, они только мешают.

Вот еще пример:
Скажем имея следующий Canvas нужно сделать SVG viewer.
Представим себе что SVG документ загружен в DOM.
Таким образом линейный проход по дереву с простой state machine + эта canvas
это все что нам нужно для rendering. И не нужны там тебе ни Color ни Pen/Brush в виде классов...
Нарисовал — и забыл.
Re[7]: canvas
От: c-smile Канада http://terrainformatica.com
Дата: 06.12.05 01:08
Оценка:
Здравствуйте, c-smile, Вы писали:

Canvas
Re[3]: macro и micro memory management. Java и С
От: IT Россия linq2db.com
Дата: 06.12.05 02:55
Оценка:
Здравствуйте, McSeem2, Вы писали:

MS>И вот у меня unmanaged объект требует довольно много памяти, а GC об этом ничего не знает и нет никакой возможности ему объяснить, что "этот объект дорогой, его надо подметать ASAP".


Может имеет смысл сделать такие объекты managed?
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: macro и micro memory management. Java и С
От: IT Россия linq2db.com
Дата: 06.12.05 03:01
Оценка: +1 -1
Здравствуйте, n0name2, Вы писали:

N>в Жабе 1.6 будет стековая аллокация — компилятор после того как выполнит все inline посмотрит можно ли все сделать на стеке или нет. т.е.


Боюсь что подобная фича будет представлять собой очередной источник багов, т.к. ожидания программистов и действия компилятора могут не совпадать. На месте разработчиков Java 1.6 я бы держал подобную фичу в большом секрете.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: macro и micro memory management. Java и С
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.12.05 03:35
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Эффективнее . Вот тебе простой пример

Все равно точнее. Если мы признаемся себе, что точки нам нужны во всех итерациях, то можно вынести их за цикл:
POINT* p = new POINT [3];
for(int i = 0; i < 1000; i++)
{
// и т.д.
}
delete [] p;

Если бы у точки был нетривиальный дефолтный конструктор, то этот код имел бы шанс быть даже эффективнее твоего варианта:

PD>for(int i = 0; i < 1000; i++)

PD>{
PD> POINT p[3];
PD> // и т.д.
PD>}

PD>1000 раз дергать кучу там, где можно и один раз не дергать — хорошая, кстати иллюстрация на тему микрооптимизации, за которую меня некоторые ругали . Вот таким невиинным кодом убивают производительность. А с точки зрения дизайна здесь вообще ничего нет — дизайн здесь близко не лежит.

PD>Конечно, я здесь использую свое знание того, что выделение памяти в стеке произведено будет 1 раз, а не 1000 (кстати, это стандартом ИМХО не определяется, формально ведь память отводится при входе в блок, так ?). Но даже если бы 1000 раз — все равно лучше 1000 раз выполнить что-то вроде add esp,..., чем 1000 раз дергать хип менеджер с его поиском в 2-linked списке.
Я вот не уверен, что надо начинать рассуждения с add esp и прочих туманных деталей. Я всегда старался запоминать наиболее общие утверждения. К тому же как раз плюсы — штука чреватая неявными эффектами. Да, для точки все действительно так, как ты говоришь. Более того, компилятор как раз способен вынести инвариант за цикл (в отличие от случая с new/delete) и получить код, близкий к оптимальному.

PD>Ну не знаю. Никакой проблемы в этом не было, размер стека в любой модели, (кроме tiny, где все вместе в 64К), был ограничен 64 К. Надо было просто _stklen установить. В конце концов никто на запрещщал же в те времена вот такие описания


PD>void f()

PD>{
PD>char a[4096] ;
PD>//....
PD>}
Да, никто и не запрещал. Вот только моя программа сразу же упала с таким описанием. Я уже не помню, что там надо было установить.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: macro и micro memory management. Java и С
От: IT Россия linq2db.com
Дата: 06.12.05 03:39
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Т.е. она идеологически правильная но практически не работает — тормозит.


Графика в .NET тормозит не по причине GC, а по пречине того, что она базируется на GDI+.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: macro и micro memory management. Java и С
От: McSeem2 США http://www.antigrain.com
Дата: 06.12.05 04:44
Оценка:
Здравствуйте, IT, Вы писали:

IT>Может имеет смысл сделать такие объекты managed?


В силу ряда причин это сделать нереально.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[5]: macro и micro memory management. Java и С
От: Pavel Dvorkin Россия  
Дата: 06.12.05 06:39
Оценка: 6 (1) +3
Здравствуйте, Sinclair, Вы писали:

S>Все равно точнее. Если мы признаемся себе, что точки нам нужны во всех итерациях, то можно вынести их за цикл:


Ну это уже изменение области видимости. А вдруг в объемлющем блоке другой p описан ?


S>Я вот не уверен, что надо начинать рассуждения с add esp и прочих туманных деталей.


Для обучения — сразу не надо. Но все же программист на С++ должен понимать. что там ниже делается. Более того, ИМХО это вообще верно — чтобы качественно программировать на уровне N, надо понимать, что делается на уровне N-1. Уметь самому программировать на уровне N-1 не обязательно.
With best regards
Pavel Dvorkin
Re: macro и micro memory management. Java и С
От: Pavel Dvorkin Россия  
Дата: 06.12.05 07:13
Оценка: :)
Здравствуйте, c-smile, Вы писали:


CS>В данном случае Java выполняет менджмент микро объектов Rect и Brush — создает и удаляет их. Как следствие система жутко не эффективная. Как правило Brush это обертка над системным HBRUSH в конце концов. Т.е. к тому же имеем еще и dispose со всеми вытекающими.


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

А почему бы в языках, работающих в управляемой среде (Java, C#) не разрешить вторичный вызов конструктора ?

class C
{
C(...) {...}
}

C c = new C(1 набор параметров);
// использовали
reconstr (c, C(другой набор параметров));

// естественно, exception, если тип c не есть C)

и т.д.

Конечно, это можно и сейчас сделать, вынеся код в отдельную функцию и вызывая его в первый раз из конструктора, а потом просто так. Но ИМХО это было бы логичнее. Т.е. я пересоздаю объект без перевыделения памяти.

В С++ это, естественно, невозможно, а в управляемой среде ИМХО нет противопоказаний. Ставшие мусором объекты из прежнего экземпляра скушает GC.

Полиморфизма так, конечно, не добьешься, но вот от перевыделения памяти иногда можно избавиться

Brush br = new Brush(Color(0,0,255));
// use blue brush
reconstr (br, Brush(Color(255,0,0));
// use red brush
With best regards
Pavel Dvorkin
Re[2]: macro и micro memory management. Java и С
От: Павел Кузнецов  
Дата: 06.12.05 07:29
Оценка:
Pavel Dvorkin,

> А почему бы в языках, работающих в управляемой среде (Java, C#) не разрешить вторичный вызов конструктора ?

>
> class C
> {
> C(...) {...}
> }
>
> C c = new C(1 набор параметров);
> // использовали
> reconstr (c, C(другой набор параметров));
>
> // естественно, exception, если тип c не есть C)
>
> <...>
>
> В С++ это, естественно, невозможно <...>

Почему?
C* c = new C(1);
. . .
c->~C();
new (c) C(2);
. . .
delete c;

проверку на совпадение типа можно организовать, используя RTTI.
Posted via RSDN NNTP Server 2.0
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: macro и micro memory management. Java и С
От: Pavel Dvorkin Россия  
Дата: 06.12.05 07:33
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Почему?


Я имел в виду без вызова деструктора.
With best regards
Pavel Dvorkin
Re[7]: macro и micro memory management. Java и С
От: n0name2  
Дата: 06.12.05 07:35
Оценка: +1
Здравствуйте, IT, Вы писали:

N>>в Жабе 1.6 будет стековая аллокация — компилятор после того как выполнит все inline посмотрит можно ли все сделать на стеке или нет. т.е.


IT>Боюсь что подобная фича будет представлять собой очередной источник багов, т.к. ожидания программистов и действия компилятора могут не совпадать. На месте разработчиков Java 1.6 я бы держал подобную фичу в большом секрете.


в том то и дело что в строго типизированной и безопасной системе можно безболезненно делать очень радикальные оптимизации в т.ч. на основе статистики собранной в рантайме. это же не C где можно делать арифметические операции над указателями...
Re[2]: macro и micro memory management. Java и С
От: n0name2  
Дата: 06.12.05 07:44
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Т.е. я пересоздаю объект без перевыделения памяти.


в Java/C# не нужны ручные оптимизации — все это может делать компилятор или рантайм автоматически. если бы это было действительно узким местом, то давно бы уже так и сделали.

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

единственное что занимает много времени это инициализация объекта (скажем, массивы при выделении инициализируются нулями, ссылки все нулевые и т.д.) но при пересоздании это тоже надо делать.
Re[8]: macro и micro memory management. Java и С
От: WolfHound  
Дата: 06.12.05 08:54
Оценка: :)
Здравствуйте, n0name2, Вы писали:

N>в том то и дело что в строго типизированной и безопасной системе можно безболезненно делать очень радикальные оптимизации в т.ч. на основе статистики собранной в рантайме. это же не C где можно делать арифметические операции над указателями...

Только тут надо иметь в виду что стек не резиновый...
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: macro и micro memory management. Java и С
От: WolfHound  
Дата: 06.12.05 09:05
Оценка: +1
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Я имел в виду без вызова деструктора.

Не забывай про финалийзеры. И про то что на объект могут быть ссылки.
Короче такая функциональность приведет к граблям. Пусть уж лучше этим оптимизатор занимается ибо в управляемых средах у него достаточно информации для таких оптимизаций.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[2]: macro и micro memory management. Java и С
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.12.05 09:25
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Такая вот мысль в голову пришла. Просьба сильно за нее не бить, если что я не додумал.


PD>А почему бы в языках, работающих в управляемой среде (Java, C#) не разрешить вторичный вызов конструктора ?


Я думаю, потому, что это нарушит ссылочную целостность. У нас уже есть ссылки в других объектах на этот объект. И эти другие объекты будут крайне удивлены внезапной смерти того объекта и возникновению нового. У меня сейчас сильнейшее дежа вю, т.к. данная тема уже точно поднималась.

PD>Конечно, это можно и сейчас сделать, вынеся код в отдельную функцию и вызывая его в первый раз из конструктора, а потом просто так. Но ИМХО это было бы логичнее. Т.е. я пересоздаю объект без перевыделения памяти.


PD>Полиморфизма так, конечно, не добьешься, но вот от перевыделения памяти иногда можно избавиться

Выделение памяти в управляемой среде — сверхестественно дешевая операция, сравнимая со стоимостью выделения памяти на стеке в C++. Не там воду ищешь.
Для тех редчайших случаев, когда действительно дешевле переинициализировать объект, чем создавать новый, можно пользоваться двухстадийной инициализацией.
Brush br = new Brush(Color(0,0,255));
br.Init(Color(0,0,255));
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: macro и micro memory management. Java и С
От: GlebZ Россия  
Дата: 06.12.05 09:46
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Только тут надо иметь в виду что стек не резиновый...

Ага, и то что запросить информацию об объекте и выполнить действия могут через внешний интерфейс типа reflection.

С уважением, Gleb.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: macro и micro memory management. Java и С
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 06.12.05 09:48
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Pavel Dvorkin,


>> А почему бы в языках, работающих в управляемой среде (Java, C#) не разрешить вторичный вызов конструктора ?

>>
>> <...>
>>
>> В С++ это, естественно, невозможно <...>

ПК>Почему?

ПК>
ПК>C* c = new C(1);
ПК>. . .
c->>~C();
ПК>new (c) C(2);
ПК>. . .
ПК>delete c;
ПК>


Вопрос терминологический, но по-моему, здесь не происходит повторного вызова конструктора
Конструктор чего вызывается повторно? Ведь объект, на который указывает c не существует после вызова соответствующего деструктора
Re[9]: macro и micro memory management. Java и С
От: n0name2  
Дата: 06.12.05 10:14
Оценка:
Здравствуйте, WolfHound, Вы писали:

N>>в том то и дело что в строго типизированной и безопасной системе можно безболезненно делать очень радикальные оптимизации в т.ч. на основе статистики собранной в рантайме. это же не C где можно делать арифметические операции над указателями...

WH>Только тут надо иметь в виду что стек не резиновый...

в общем да — ну так рантайм знает в точности сколько что занимает и совершенно свободно посчитает сколько туда можно пихать.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.