
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (56) « Первая ... 29 30 [31] 32 33 ... 55 56 ( Перейти к последнему сообщению ) |
Сообщ.
#451
,
|
|
|
Цитата D_KEY @ Эм, потенциал таков, что ты можешь отказаться от GC полностью.Мне интересен потенциал опционального сборщика. Тут же заход немного с другой стороны. Цитата D_KEY @ Не совсем понимаю, что значит работать с объектами в GC или не GC. Какая разница для контейнера откуда взялась память для объектов (если конечно эту память не выделяет сам контейнер)?А для контейнеров что? Аллокаторы? Т.е. умеют ли контейнеры работать с объектами в GC и не в GC? Что касается аллокаторов, то на данный момнет нет встроенных в стандартную либу контейнеров умеющих использовать аллокаторы. Александреска только собирается их писать. Есть сторонние либы с контейнерами и аллокаторами, также есть сторонние реализации аналогов shared_ptr и unique_ptr. Напрямую с GC не связано, но связано с аллокациями. Функции возвращающие ленивые ренджи никогда не делают аллокаций памяти. В стандартной либе вроде есть RefCounted и Unique но они почему-то не работают с классами (не в смысле глючат, а в смысле запрограмиированы не принимать классы). На форуме идут дискуссии. Александреску помешан на безопасности, а библиотечная реализация таких объектов действительно не может быть полностью безопасной. Ему отвечают: ну и что? Пусть будет небезопасно, живут же всякие shared_ptr/unique_ptr - все довольны. Конечно же все кому сильно надо написали свои велосипеды на эту тему. Ну а Александреска предлагает встроить поддержку RC-объектов непосредственно в язык шобы было ну ваще безопасно. По мне так это перебор. В крайнем случае достаточно изобрести очередной аттрибут, для пометки RC-объектов, чтобы компилятор знал, что это RC и пресекал попытки вынести из комнаты кишки такого объекта. Это относительно большая тема. В D кроме модификатора const есть еще модификатор immutable. По отношению к value-типам особой разницы между ними нет. А вот для ссылочных объектов разница существенна. Если функция получила в качестве параметра const-объект, то это значит, что она гарантирует неизменность этого объекта. При этом такой объект может быть изменен где-то в другом месте (например, в другом потоке). То есть наша функция сама дает гарантии неизменности, но не получает таковых. Если же функция получила в качастве параметра immutable-объект, то это значит что она получает гарантию, что никто (в том числе и она сама) не может изменить (в том числе и уничтожить) этот объект нигде и никогда. То есть immutable-объекты можно спокойно распространять по всей программе, в том числе мужду потоками без синхронизации и без счетчика ссылок. Я не представляю как сделать такое поведение объектов без GC. В моем проекте постоянно создаются и уничтожаются небольшие иммутабельные объекты. Эти объекты не менее постоянно курсируют между потоками в виде иммутабельных же массивов, слайсов на иммутабельные массивы или ленивых ренджей поверх иммутабельных массивов. Благодаря иммутабельности и GC я могу это делать безопасно и без утечек полностью забив на синхронизацию и головную боль с временем жизни этих объектов и массивов, в которых они лежат. В C++ пришлось бы использовать shared_ptr (без гарантий иммутабельности, а значит небезопасно), который при каждом копировании создает write barrier со всеми вытекающими, а так как такие копирования происходят постоянно и в больших количествах, то можно поспорить, что будет производительнее: весь такой zero-abstraction-cost shared_ptr или обычные указатели с якобы тормозным GC. |
Сообщ.
#452
,
|
|
|
Цитата applegame @ В C++ пришлось бы использовать shared_ptr Зачем, если объект иммутабельный? Все его копии равнозначны. Отдайте в другой поток его копию. И тогда уже нельзя будет поспорить, что производительнее: стек или черепаха GC. Цитата applegame @ без гарантий иммутабельности, а значит небезопасно Вы тут вообще мешаете понятия неизменяемости и умные указатели. Это вещи ортогональные. shared_ptr не привносит никакой небезопасности, кроме той, что уже есть в языке. |
Сообщ.
#453
,
|
|
|
Цитата applegame @ Эм, потенциал таков, что ты можешь отказаться от GC полностью. И страдать? ![]() Цитата Какая разница для контейнера откуда взялась память для объектов (если конечно эту память не выделяет сам контейнер)? Цитата Что касается аллокаторов, то на данный момнет нет встроенных в стандартную либу контейнеров умеющих использовать аллокаторы. Так а кто выделяет память? Память для элементов лежит в GC? Цитата Это относительно большая тема. В D кроме модификатора const есть еще модификатор immutable. По отношению к value-типам особой разницы между ними нет. А вот для ссылочных объектов разница существенна. Если функция получила в качестве параметра const-объект, то это значит, что она гарантирует неизменность этого объекта. При этом такой объект может быть изменен где-то в другом месте (например, в другом потоке). То есть наша функция сама дает гарантии неизменности, но не получает таковых. Если же функция получила в качастве параметра immutable-объект, то это значит что она получает гарантию, что никто (в том числе и она сама) не может изменить (в том числе и уничтожить) этот объект нигде и никогда. Это понятно и знакомо. Цитата То есть immutable-объекты можно спокойно распространять по всей программе, в том числе мужду потоками без синхронизации и без счетчика ссылок. Я не представляю как сделать такое поведение объектов без GC. По мне так управление памятью ортогонально иммутабельности. Так а почему без счетчика ссылок-то? Как он мешает immutable? ![]() ![]() struct A { const int a; const int b; }; // если являемся одним из владельцев void thread_fun(std::shared_ptr<A> obj) { // читаем сколько влезет из obj без синхронизации } // если не являемся владельцем void thread_fun(const A & obj) { // читаем сколько влезет из obj без синхронизации } Цитата В моем проекте постоянно создаются и уничтожаются небольшие иммутабельные объекты. Эти объекты не менее постоянно курсируют между потоками в виде иммутабельных же массивов, слайсов на иммутабельные массивы или ленивых ренджей поверх иммутабельных массивов. Ну это вполне может жить или на подсчете ссылок или с удалением объектов при завершающей обработке(если таковая имеется) или каким-то сочетанием этого. GC тут, конечно, упрощает жизнь, но иммутабельность тут ни при чем, ИМХО. Цитата В C++ пришлось бы использовать shared_ptr (без гарантий иммутабельности, а значит небезопасно) Почему без гарантий иммутабельности? Цитата который при каждом копировании создает write barrier со всеми вытекающими, а так как такие копирования происходят постоянно и в больших количествах Почему постоянно? Почему в больших количествах? Очень часто тебе вообще достаточно unique_ptr и каких-то очередей/каналов между воркерами. Нет? Цитата то можно поспорить, что будет производительнее: весь такой zero-abstraction-cost shared_ptr или обычные указатели с якобы тормозным GC. Ну в такой постановке да. Сейчас речь не о холиваре "GC против всех", а о том, насколько хорошо в языке может жить опциональный сборщик. |
Сообщ.
#454
,
|
|
|
Цитата MyNameIsIgor @ Копирование массивов или глубокое копирование объектов содержащих другие объекты - не очень-то производительное решение. Речь идет об указателях на immutable-данные.Зачем, если объект иммутабельный? Все его копии равнозначны. Отдайте в другой поток его копию. И тогда уже нельзя будет поспорить, что производительнее: стек или черепаха GC. Цитата MyNameIsIgor @ Не совсем ортогональные. Умный указатель не может быть "честно" иммутабельным по определению. А значит не может содержаться в другом иммутабельном объекте.Вы тут вообще мешаете понятия неизменяемости и умные указатели. Это вещи ортогональные. Цитата D_KEY @ Страдать? Не более, чем в C++. Если сначала жил с GC, а тут, опа, и нужно от него отказаться, тогда да, будешь страдать. И страдать? ![]() ![]() Цитата D_KEY @ Эту уже от самого контейнера зависит. Пока все встроенные в стандартную либу контейнеры берут память исключительно у GC. Контейнеры построенные на базе аллокаторов берут память собственно у аллокатора, в качестве которого может выступать также и GC. То есть это уже будут универсальные контейнеры. По умолчанию память хапается у GCAllocator, а там можно переключиться на Mallocator или какой-нибудь FreeListAllocator с бэкендом на том же GCAllocator/Mallocator.Так а кто выделяет память? Память для элементов лежит в GC? Цитата D_KEY @ Я так не считаю. ИМХО, честную иммутабельность принципиально нельзя сделать без GC. Возможно я ошибаюсь, эта тема весьма интересна мне, посему - Цитата По мне так управление памятью ортогонально иммутабельности.То есть immutable-объекты можно спокойно распространять по всей программе, в том числе мужду потоками без синхронизации и без счетчика ссылок. Я не представляю как сделать такое поведение объектов без GC. ![]() Цитата D_KEY @ Дык, объект-то нифига не иммутабельный, то бишь владелец объекта может его легально изменить (например по ошибке программиста) без сопротивления со стороны компилятора, и второй поток прочитает половину объекта со старыми данными, а половину с новыми, нарушив какой-нибудь инвариант. Так а почему без счетчика ссылок-то? Как он мешает immutable? ![]() ![]() struct A { const int a; const int b; }; // если являемся одним из владельцев void thread_fun(std::shared_ptr<A> obj) { // читаем сколько влезет из obj без синхронизации } // если не являемся владельцем void thread_fun(const A & obj) { // читаем сколько влезет из obj без синхронизации } Цитата D_KEY @ Ну смотри сам. У меня есть достаточно большое количество (сотни тысяч) относительно небольших объектов. Эти объекты хрянятся в некой структуре, что-то вроде весьма узкоспециализированной простой БД в памяти. Также есть множество потоков, которые работают с какими-то срезами из этой БД, обычно lazy-range/слайсы, иногда небольшие иммутабельные масивы по нескольку десятков объектов. Причем несколько потоков могут одновременно работать с одними и теми же объектами. Объекты регулярно уничтожаются и создаются новые. Можно было действительно просто копировать все целиком и отправлять копии другим потокам, но это я посчитал очень неэффективным в плане производительности, да и зачем, если все иммутабельное, и я могу спокойно слать потокам только указатели на эта данные.Цитата который при каждом копировании создает write barrier со всеми вытекающими, а так как такие копирования происходят постоянно и в больших количествах Почему постоянно? Почему в больших количествах? Очень часто тебе вообще достаточно unique_ptr и каких-то очередей/каналов между воркерами. Нет? Цитата D_KEY @ Хз, по мне "опциональный" не совсем корректное выражение. Сам язык не требует GC, кроме считанных фич. И тут не стоит впрос использовать эти фичи с GC или без. Либо с фичами и с GC, либо без GC и без фич. Лишение этих фич доставляет страдания только тем, кто ими раньше активно пользовался. Скажем плюсовики и раньше не могли взять и склеить два массива специальной конструкцией языка, так что лишение такой возможности в D они даже не заметят. Сейчас речь не о холиваре "GC против всех", а о том, насколько хорошо в языке может жить опциональный сборщик. |
Сообщ.
#455
,
|
|
|
Цитата applegame @ Умный указатель не может быть "честно" иммутабельным по определению |
Сообщ.
#456
,
|
|
|
Цитата MyNameIsIgor @ "Честно" иммутабельный - это который действительно не меняет свое внутреннее состояние, а не делает вид, что не меняет, а на самом деле меняет. Что такое "честно" иммутабельный по определению? |
Сообщ.
#457
,
|
|
|
Цитата applegame @ Умный указатель не может быть "честно" иммутабельным по определению. Почему не может? И зачем ему быть иммутабельным, если нужен иммутабельный объект, а указатель можно копировать. Или тебя смущают изменяемые счетчики? Но это внутренние потроха, потокобезопасность же тебе гарантируется. Цитата Страдать? Не более, чем в C++. Ну как не более, если даже контейнеры без GC не работают в D? Цитата ИМХО, честную иммутабельность принципиально нельзя сделать без GC. А почему? Цитата Дык, объект-то нифига не иммутабельный, то бишь владелец объекта может его легально изменить (например по ошибке программиста) без сопротивления со стороны компилятора Там же константные поля. Так что с сопротивлением ![]() Покажи код(лучше на C++, чтобы не было недоразумений). Ну смотри сам. У меня есть достаточно большое количество (сотни тысяч) относительно небольших объектов. Эти объекты хрянятся в некой структуре, что-то вроде весьма узкоспециализированной простой БД в памяти. Также есть множество потоков, которые работают с какими-то срезами из этой БД, обычно lazy-range/слайсы, иногда небольшие иммутабельные масивы по нескольку десятков объектов. Причем несколько потоков могут одновременно работать с одними и теми же объектами. Объекты регулярно уничтожаются и создаются новые. Можно было действительно просто копировать все целиком и отправлять копии другим потокам, но это я посчитал очень неэффективным в плане производительности, да и зачем, если все иммутабельное, и я могу спокойно слать потокам только указатели на эта данные. Цитата Сам язык не требует GC, кроме считанных фич. И контейнеров, например ![]() |
Сообщ.
#458
,
|
|
|
Цитата applegame @ "Честно" иммутабельный - это который действительно не меняет свое внутреннее состояние, а не делает вид, что не меняет, а на самом деле меняет. Что такое "действительно не меняет своё внутреннее состояние"? У меня есть тип T, разработчик которого Вася уверяет, что он иммутабельный, как мне проверить слова Васи? |
Сообщ.
#459
,
|
|
|
Цитата applegame @ Цитата MyNameIsIgor @ "Честно" иммутабельный - это который действительно не меняет свое внутреннее состояние, а не делает вид, что не меняет, а на самом деле меняет.Что такое "честно" иммутабельный по определению? Так какая разница, если тебе предоставляют гарантии корректной работы счетчиков RC в многопоточной среде? |
Сообщ.
#460
,
|
|
|
Цитата D_KEY @ Ну как не более, если даже контейнеры без GC не работают в D? Цитата D_KEY @ И контейнеров, например ![]() Контейнеры - это не D, это библиотеки. В сторонних библиотеках (которые можно поставить дешным пакетным менеджером dub) есть контейнеры с аллокаторами, RC и прочая. То что нет в стандартной - это да печаль и говно. Цитата D_KEY @ А что будет если владелец уничтожит объект? Например первый поток закончит работу раньше второго?Там же константные поля. Так что с сопротивлением ![]() Цитата MyNameIsIgor @ Это гарантия того, что в любой момент времени можно прочитать это состояние и оно всегда будет одним и тем же. Допустим некий компилятор увидев, что данный объект иммутабельный, и со спокойной совестью берет и помещает его в область памяти с защитой от записи. И если Вася вас обманул, то в какой-то момент ваше приложение упадет. Что такое "действительно не меняет своё внутреннее состояние"? У меня есть тип T, разработчик которого Вася уверяет, что он иммутабельный, как мне проверить слова Васи? |
Сообщ.
#461
,
|
|
|
Цитата applegame @ Это гарантия того, что в любой момент времени можно прочитать это состояние и оно всегда будет одним и тем же. Допустим некий компилятор увидев, что данный объект иммутабельный, и со спокойной совестью берет и помещает его в область памяти с защитой от записи. Не понимаю, как из гарантии того, что я прочитаю одно и то же состояние, следует, что объект может быть в области с защитой от записи? |
Сообщ.
#462
,
|
|
|
Цитата D_KEY @ Тут дело в безопасности. Зачем, например, нужен модификатор const, если тебе предоставляют гарантии, что эта вот функция, мамой клянус, не изменяет состояние этого вот объекта? То есть то что касается именно shared_ptr, то тут никаких сомнений нет. Я знаю, что он меняет cвое состояние (счетчик), и его константные функции не совсем константные (так как опять же меняют счетчик), но на это можно закрыть глаза, так как это работает. Но если вот этот тип T для меня сделал Вася, то я бы очень хотел, чтобы его const функции были бы на самом деле const. А то я создам immutable глобальную переменную типа T, компилятор запихнет ее в data-сегмент, а тут выяснится, что const-функция оказалась не const и все дело падает в ран-тайме. Нехорошо, Вася. Нехорошо. Так какая разница, если тебе предоставляют гарантии корректной работы счетчиков RC в многопоточной среде? Добавлено Цитата MyNameIsIgor @ не просто прочитаете одно и тоже состояние, а в любой момент времени прочитаете одно и тоже состояние, из чего следует, что никто и никогда не должен изменять эти данные.Не понимаю, как из гарантии того, что я прочитаю одно и то же состояние, следует, что объект может быть в области с защитой от записи? Почему бы параноидальному компилятору и не засунуть этот объект в область с защитой от записи? Более того, компиляторы в некоторых случаях так и делают. Например строковые литералы в C++/D "честно" иммутабельные. В линупсе попытка записи в такой литерал приведет к сегфолту. |
Сообщ.
#463
,
|
|
|
Цитата applegame @ не просто прочитаете одно и тоже состояние, а в любой момент времени прочитаете одно и тоже состояние, из чего следует, что никто и никогда не должен изменять эти данные. Дададада. Цитата applegame @ Почему бы параноидальному компилятору и не засунут этот объект в область с защитой от записи? Более того компиляторы в некоторых случаях так и делают На каком основании? С чего вы вообще взяли, что всегда читать одно и то же состояние - это всё равно, что в объект никто не пишет? Добавлено Я, конечно, троллю. И знаю, что поскольку в D было слабо вставить зависимые типы, сделали тупо побитовую неизменность, назвали это безопасностью и вот теперь адепты этого недоязыка познают понятие неизменяемости через призму D. Печально, фигли... |
Сообщ.
#464
,
|
|
|
Цитата MyNameIsIgor @ А кому было не слабо вставить зависимые типы? Idris? ATS? Такие чисто ситемные языки приближенные к hardware. И совсем не академические. Я, конечно, троллю. И знаю, что поскольку в D было слабо вставить зависимые типы, сделали тупо битовую неизменность, назвали это безопасностью и вот теперь адепты этого недоязыка познают понятие неизменяемости через призму D. Печально, фигли... ![]() И зря вы так об адептах D. Я понимаю, что иммутабельность через битовую неизменность - это суррогат, но можете ли вы предложить что-нибудь лучше? |
Сообщ.
#465
,
|
|
|
Цитата applegame @ Я понимаю, что иммутабельность через битовую неизменность - это суррогат, но можете ли вы предложить что-нибудь лучше? Да любой функциональный язык может. Там все сущности иммутабельны, но почему-то не расположены в памяти с защитой от записи. Интересно, почему? ![]() Добавлено Цитата applegame @ Такие чисто ситемные языки приближенные к hardware. И совсем не академические. Проблема в том, что если хочется приблизиться к "железу", то чем-то надо жертвовать. Я не понимаю обеспечение безопасности с помощью изъятия у всех кухонных ножей. |