Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
E>>>То есть, ты хочешь ссказать, что такой код
char buffer[sizeof( T )];
E>>>delete new( buffer )T;
не валиден? J>>Почему не валиден? Откуда это следует? E>Из твоего утверждения, что объект может содержать данные по отрицательному смещению.
так мы уже, вроде, не отрицательное смещение обсуждаем, а теневое хранение, а ему он не противоречит (по крайенй мере, я не вижу, как).
J>>Тут я никаких проблем не вижу. Адресная арифметика никуда не делась, просто она будет ходить по указателям на хэндлы. J>>Она все равно определена только для массивов, так что внутри объектов ее юзать некооректно. E>А если приватное поле -- массив?
И что? внутри этого массива — можно, а снаружи (внутри содержащего его объекта) — по-прежнему нельзя.
J>>Со storage вообще проблем не вижу. E>Проблема в том, что storage -- это память, занимаемая объектом. НИкакого "теневого storage" вроде как не предусмотрено
Что значит — "память, занимаемая объектом"? по стандарту, в смысле.
E>>>Скажем как ты будешь обрабатывать ситуацию, при которой ты создаёшь объект по new размещениея, а памячть в твоём "теневом хранилоище объектов" закончилась? J>>Останавливать программу. Других вариантов стандарт не дает, из-за 18.4.1.3/1-3. E>А разве останавливать можно?
останавливать всегда можно Это как переполнение стека: вроде и корректная программа, а дальше работать нельзя, потому что машина не тянет. Здесь точно такой же случай.
J>>Если б позволяли — кинул бы bad::alloc. E>Мне кажется, что new размещениея не может не работать...
по стандарту — да, я же и сказал, что не позволяет.
Да и в любом случае, даже если ты сейчас мне докажешь, что схема с теневым хранением несовместима со стандартом — это будет лишь означать несовместимость данной конкретной схемы. Вполне возможно, что существует другая(ие), которая будет самым лучшим решением в каких-нибудь экзотических условиях, и будет на 100% удовлетворять стандарту.
E>Интересно бы понять чем оно вызвано. Я всё ещё думаю, что это баг.
Ну, можно поспрашивать членов комитета, чем это вызвано. Я не знаю.
E>>>Нет, любой указатель можно привести к const char* и получить доступ к бинарному представлению данных... J>>ссылку на стандарт дашь? E>КОгда встречусь с текстом -- дам. Но, кроме описания того, к чему можно приводить указатели, стандарт ещё сожержит подробное очень описание работы перекрытых operator new/delete. И там очень активно используется идея занимаемой объектом памяти. Так что твоя реализация, IMHO, не пролезет
Ну, аргументируй цитатами, обсудим.
E>>>Ну перебдеть-то это не мешает? С невозможностью двигать содержимое std::vector по памяти перебдели же? J>>еще раз — на каких условиях ее реализовывать? J>>По умолчанию это можно делать только для подов, но и с подами беда — вот у меня прямо сейчас есть структуры с указателями внутрь, хоть и поды. Если их передвинуть — все слетит нафиг. E>Ну я тоже согласен, что возможность двигать объекты по памяти никак не связана с их POD'овостью...
J>>Стало быть, надо отдельный механизм предусматривать, правильно? А, во-первых, продумать, как это правильно сделать (вариантов куча, и с наскоку не видно, какой лучше), чтоб все удобно было — на это время нужно, а во-вторых, это оптимизация, а для начала надо предоставить базовую функциональность, что и было сделано. E>Без этого std:vector малоюзабелен .
И? Где твое предложение по настройке двигания содержимого? И уверен ли ты, что оно — единственно правильное и никто потом не скажет: "могли бы заняться чем-то полезным, а не замораживанием егоровского поделия навека?"
E>Интересно было бы понимать зачем вообще было выбрано требование на элемент контейнера иметь семантику значения. Необъодимым оно не является, необременительным тоже...
Безопасностью. Все остальные схемы предполагают ручное управление временем жизни элементов.
E>Вообще в дизайне STL лично мне очень не нравится отсутсвие целенаправленности. Скажем вот добавили в контейнеры аллокаторы. При этом зачем это сделали не понятно. Ни возмоэность передать контейнеру конкретный пул памяти не предусмотрели, ни возможность гранулировать аллокации. Результат печальный -- аллокаторы есть, а толку нет. И так во многих очень местах
Ну, аллокаторы еще только ленивый не пнул.
Но в то время просто еще не изобрели подходов типа тех, что применены в бусте (см. аллокаторы у boost::shared_ptr).
Кстати, в бусте новые методы были применены и для конструирования, см. boost::inplace_factory.
И, кстати, изначально буст появился как раз для хранения и доведения до состояния интеграции предложений в стандартную библиотеку.
Здравствуйте, jazzer, Вы писали:
E>>А если приватное поле -- массив? J>И что? внутри этого массива — можно, а снаружи (внутри содержащего его объекта) — по-прежнему нельзя. J>>>Со storage вообще проблем не вижу.
Ещё бывают объединения, кстати.
J>Что значит — "память, занимаемая объектом"? по стандарту, в смысле.
Читай вокруг operator new. Что именно он возвращает.
J>Да и в любом случае, даже если ты сейчас мне докажешь, что схема с теневым хранением несовместима со стандартом — это будет лишь означать несовместимость данной конкретной схемы. Вполне возможно, что существует другая(ие), которая будет самым лучшим решением в каких-нибудь экзотических условиях, и будет на 100% удовлетворять стандарту.
Окей, тогда значит в её обсуждении нет никакого смысла. IMHO, даказательнйо силы она всё равно не имеет, так что в том, что обсуждаемое ограничение в стандарте не есть акт перебдения ты меня не убедил.
E>>Без этого std:vector малоюзабелен . J>И? Где твое предложение по настройке двигания содержимого? И уверен ли ты, что оно — единственно правильное и никто потом не скажет: "могли бы заняться чем-то полезным, а не замораживанием егоровского поделия навека?"
Мои предложения были бы слишком поздно. Но были и не мои. Только толку не было.
E>>Интересно было бы понимать зачем вообще было выбрано требование на элемент контейнера иметь семантику значения. Необъодимым оно не является, необременительным тоже... J>Безопасностью. Все остальные схемы предполагают ручное управление временем жизни элементов.
Да? И как безопасность связана с копируемостью содержимого std::map, например?
E>>Вообще в дизайне STL лично мне очень не нравится отсутсвие целенаправленности. Скажем вот добавили в контейнеры аллокаторы. При этом зачем это сделали не понятно. Ни возмоэность передать контейнеру конкретный пул памяти не предусмотрели, ни возможность гранулировать аллокации. Результат печальный -- аллокаторы есть, а толку нет. И так во многих очень местах J>Ну, аллокаторы еще только ленивый не пнул.
Проблема не в том, что они плохи, и не придумали хороших, а в том, что добавили в стандарт не пойми что не пойми зачем.
J>И, кстати, изначально буст появился как раз для хранения и доведения до состояния интеграции предложений в стандартную библиотеку.
В этом смысле он безусловно позитивен. Один shared_ptr оправдывает его существование рядом с STL. Хотя, IMHO, именно уродливость STL породила буст. Но в основном буст -- это склад понравившихся кому-то экспериментов, а не хорошая библиотека или коллекция хороших библиотек.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Kluev, Вы писали:
... ЮЖ>>>>Далеко не факт что 'фейлдизайн'. shared_ptr это все же shared_ptr, со своей семантикой и возможностями, например: weak_ptr и возможностью указания своего deleter'a. При необходимости последнего, использование 'умного конетйнера' практически невозможно.
K>>>если в контейнере лежат обьекты с разными deleter'aми, то это явный признак фейлдизайна. ЮЖ>>А в чем тогда принципиальное отличие от объектов с 'virtual void release()' или с виртуальным деструктором?
K>Умный конетйнер может вызывать либо деструктор либо release. т.е. что-то одно.
Я немного о другом: по сути deleter это и есть "virtual void release()", т.е. он может иметь разную реализацию(как и виртуальный деструктор).
Здесь-то в чем фейлдизайн?
K>когда ты сказал что deleter-ы круче...
Это где я такое говорил ?
ЮЖ>>Без упоминания строк это тоже был сфероконь... Мне, например, куда важнее асимптотика различных операций чем разница констант в O-нотации. Имхо, первоочередные(при возможности) оптимизации — это смена алгоритмов с квадратичных на линейные или логарифмические, например. Это дает куда больший выигрыш чем оптимизация самих этих алгоритмов. Потом уже можно и профайлер подключать, аллокаторы менять и т.п.
K>а мне важнее время выполнения...
Мне тоже. только вот оно из асимтотики следует...
K>>>>>Имхо, более правильным решением были бы базовые классы контейнера с виртуальными функциями выделения/освобождения памяти ЮЖ>>>>Получаем vtbl сотоварищи, и лишаемся no-throw гарантии для swap. K>>>по сравнению с получеными удобствами не велика потеря. ЮЖ>>no-throw swap не велика потеря ? K>Для одинаковых классов no-throw выполняется,
Это я услышал слово "виртуальными" и подумал что предполагается полиморфная работа с контейнером.
K>к тому же обычно свап для векторов используют как move.
В присутствии no-throw swap относительно легко реализуется транзакционность и обеспечение strong guarantee при возникновении исключений.
ЮЖ>>А что в строках нужно кастомизировать ? Строки это вообще вещь такая... неоднозначная. каждому надо что-то свое кастомизировать. K>внутренний буфер, например, кастомизировать нельзя. может у меня все строки размером гораздо больше чем этот буффер и смысла в нем для меня нет.
Вот я о том и говорю: если кто-то не находит способа кастомизации "своего" аспекта в неком классе/библиотеке/etc., то начинают его ругать. Только вот всех аспектов не предусмотришь...
Здравствуйте, Erop, Вы писали:
E>>>Вообще в дизайне STL лично мне очень не нравится отсутсвие целенаправленности. Скажем вот добавили в контейнеры аллокаторы. При этом зачем это сделали не понятно. Ни возмоэность передать контейнеру конкретный пул памяти не предусмотрели, ни возможность гранулировать аллокации. Результат печальный -- аллокаторы есть, а толку нет. И так во многих очень местах J>>Ну, аллокаторы еще только ленивый не пнул. E>Проблема не в том, что они плохи, и не придумали хороших, а в том, что добавили в стандарт не пойми что не пойми зачем.
из стандарта:
...allocators, which are objects that encapsulate the information about an allocation model. This information includes the knowledge of pointer types, the type of their difference, the type of the size of objects in this allocation model, as well as the memory allocation and deallocation primitives for it.
Не знаю как в embedded, но в там где видел, их используют только в качестве "memory allocation and deallocation primitives", а предназначались они не только(far/near и т.п, что уже наверное является атавизмом) для этого.
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Не знаю как в embedded, но в там где видел, их используют только в качестве "memory allocation and deallocation primitives", а предназначались они не только(far/near и т.п, что уже наверное является атавизмом) для этого.
А разве far/near стандартны? В любом случае не понятно почему и за что все экземпляторы аллокатора объявили эквивалентными...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>>Не знаю как в embedded, но в там где видел, их используют только в качестве "memory allocation and deallocation primitives", а предназначались они не только(far/near и т.п, что уже наверное является атавизмом) для этого.
E>А разве far/near стандартны?
Нет конечно, просто это вписывается в allocation model, о которой говорится в стандарте.
E>В любом случае не понятно почему и за что все экземпляторы аллокатора объявили эквивалентными...
С некоторой натяжкой они все же могут быть эквивалентными:
20.1.5
"Implementors are encouraged to supply libraries that can accept allocators that encapsulate more general
memory models and that support nonequal instances. In such implementations, any requirements imposed
on allocators by containers beyond those requirements that appear in Table 32, and the semantics of containers
and algorithms when allocator instances compare nonequal, are implementation-defined."
Тут вот какая проблема: если два объекта аллокатора равны(в терминах оператора ==), то из этого следует, что память выделенную одним объектом, можно освободить другим(20.1.5). А что делать контейнерам с различными объектами аллокаторов при присвоении, swap'ах и некоторых других операциях(list::splice) операциях ? Вариантов несколько: запретить, разрешить(и получить кидающий swap за O(N) с изменением гарантий по complexity связанных операций), либо изменить аллокаторы...
Другая проблема, не относящаяся к эквивалентности, в том что тип allocator<T>::pointer обязан быть T*. Т.е. какой-либо смарт-поинтер использовать нельзя.
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Другая проблема, не относящаяся к эквивалентности, в том что тип allocator<T>::pointer обязан быть T*. Т.е. какой-либо смарт-поинтер использовать нельзя.
Ну это, хотя бы понятно, что могли и не предусмотреть.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Юрий Жмеренецкий, Вы писали: ЮЖ>С некоторой натяжкой они все же могут быть эквивалентными:
ОписАлся, должно быть: 'могут быть _не_ эквивалентными'
Здравствуйте, Kluev, Вы писали:
K>при небольшом числе элементов разницей можно пренебречь, но при увеличении их числа map начинает безнадежно отставать.
Это ты лукавишь.
При небольшом числе элементов хеш сливает стандартному мапу, у меня есть по крайней мере два таких случая в проекте, когда хеш (с хорошей хеш-функцией) работал хуже, чем std::map (с хорошей же операцией сравнения), и в моем случае этой разницей ну никак нельзя было пренебречь. (В случае большого числа элементов хеш выигрывал, но у меня не тот случай в этих двух конкретных местах)
Здравствуйте, jazzer, Вы писали:
J>При небольшом числе элементов хеш сливает стандартному мапу, у меня есть по крайней мере два таких случая в проекте, когда хеш (с хорошей хеш-функцией) работал хуже, чем std::map (с хорошей же операцией сравнения), и в моем случае этой разницей ну никак нельзя было пренебречь. (В случае большого числа элементов хеш выигрывал, но у меня не тот случай в этих двух конкретных местах)
А что за хэш? И по чём проигрывал? По памяти или по скорости?
По идее это как-то странно, что дерево эффективнее хэш-таблицы. Возможно, правда, у таблицы слишком дорогая инициализация, конечно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
J>>При небольшом числе элементов хеш сливает стандартному мапу, у меня есть по крайней мере два таких случая в проекте, когда хеш (с хорошей хеш-функцией) работал хуже, чем std::map (с хорошей же операцией сравнения), и в моем случае этой разницей ну никак нельзя было пренебречь. (В случае большого числа элементов хеш выигрывал, но у меня не тот случай в этих двух конкретных местах)
E>А что за хэш? И по чём проигрывал? По памяти или по скорости? E>По идее это как-то странно, что дерево эффективнее хэш-таблицы. Возможно, правда, у таблицы слишком дорогая инициализация, конечно...
по скорости
Здравствуйте, jazzer, Вы писали:
E>>По идее это как-то странно, что дерево эффективнее хэш-таблицы. Возможно, правда, у таблицы слишком дорогая инициализация, конечно... J>по скорости
А реализация какая?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
E>>>По идее это как-то странно, что дерево эффективнее хэш-таблицы. Возможно, правда, у таблицы слишком дорогая инициализация, конечно... J>>по скорости E>А реализация какая?
разные пробовал, от STLPort до самописных и сгенеренных mph.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Kluev, Вы писали:
K>>чесно говоря я так и не понял для чего нужен этот класс, прочитав что это "многомерный массив" как-то пытался его использовать как двумерный массив, но так и не понял как в нем обратится к элементу по индексу [i,j].
J>через слайсы, или как они там называются.
прежде чем советовать попробывал бы сам. чтобы "удобство" оценить.
вот это: J>Если ты знаком с BLAS, то не должно быть проблем (я не знаком и с многомерными массивами по долгу службы не общаюсь).
очень плохо сочетается вот с этим: J>Вообще-то этот самый "вектор значений, который я не помню как зовут" и есть многомерный массив, причем в лучших традициях скоростных библиотек этих самых массивов.
Здравствуйте, Kluev, Вы писали:
K>>>чесно говоря я так и не понял для чего нужен этот класс, прочитав что это "многомерный массив" как-то пытался его использовать как двумерный массив, но так и не понял как в нем обратится к элементу по индексу [i,j].
J>>через слайсы, или как они там называются. K>прежде чем советовать попробывал бы сам. чтобы "удобство" оценить.
K>вот это: J>>Если ты знаком с BLAS, то не должно быть проблем (я не знаком и с многомерными массивами по долгу службы не общаюсь). K>очень плохо сочетается вот с этим: J>>Вообще-то этот самый "вектор значений, который я не помню как зовут" и есть многомерный массив, причем в лучших традициях скоростных библиотек этих самых массивов.
Что конкретно тебя смутило? Я не вижу противоречия. Или BLAS — это уже не скоростная библиотека?
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Kluev, Вы писали:
K>>при небольшом числе элементов разницей можно пренебречь, но при увеличении их числа map начинает безнадежно отставать.
J>Это ты лукавишь. J>При небольшом числе элементов хеш сливает стандартному мапу, у меня есть по крайней мере два таких случая в проекте, когда хеш (с хорошей хеш-функцией) работал хуже, чем std::map (с хорошей же операцией сравнения), и в моем случае этой разницей ну никак нельзя было пренебречь. (В случае большого числа элементов хеш выигрывал, но у меня не тот случай в этих двух конкретных местах)
свежо предание, но верится с трудом. хеш может сливать только в том случае когда хеш-функция дает много коллизий
или задан небольшой размер таблицы и много одинаковых значений hash%table_size. если у тебя отличная хеш функция — производителность достигается увеличением размера таблицы.
подбросив побольше памяти можно добится, что по каждому индексу hash%table_size будет сидеть один элемент. map должен быть совсем небольших размеров чтобы работать в этом случаее эффективнее hash. а на небольших размерах вместо map можно вполне обойтись отсортированным вектором.
Имхо, у тебя какая-то очень радкая и полумифическая ситуация если не подходят ни hash ни сортированный массив.
Здравствуйте, Kluev, Вы писали:
K>подбросив побольше памяти можно добится, что по каждому индексу hash%table_size будет сидеть один элемент. map должен быть совсем небольших размеров чтобы работать в этом случаее эффективнее hash. а на небольших размерах вместо map можно вполне обойтись отсортированным вектором. K>Имхо, у тебя какая-то очень радкая и полумифическая ситуация если не подходят ни hash ни сортированный массив.
Большую таблицу долго инициализировать...
Правда массив должен подходить для совсем маленьких коллекций...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jazzer, Вы писали:
K>>вот это: J>>>Если ты знаком с BLAS, то не должно быть проблем (я не знаком и с многомерными массивами по долгу службы не общаюсь). K>>очень плохо сочетается вот с этим: J>>>Вообще-то этот самый "вектор значений, который я не помню как зовут" и есть многомерный массив, причем в лучших традициях скоростных библиотек этих самых массивов.
J>Что конкретно тебя смутило? Я не вижу противоречия. Или BLAS — это уже не скоростная библиотека?
смутило то, что ты берешься рассуждать о том с чем не работаешь.
Здравствуйте, Kluev, Вы писали:
K>смутило то, что ты берешься рассуждать о том с чем не работаешь.
Ты с этим тоже не работаешь, вроде как.
Я, по-моему, сразу же сказал, что в реальной работе его не использовал. Но что он сделан по образцу фортрановских ЛА-библиотек для векторных процессоров — это, вроде, факт, не зависящий от того, работал я с библиотекой или нет.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Kluev, Вы писали:
K>>смутило то, что ты берешься рассуждать о том с чем не работаешь.
J>Ты с этим тоже не работаешь, вроде как.
J>Я, по-моему, сразу же сказал, что в реальной работе его не использовал. Но что он сделан по образцу фортрановских ЛА-библиотек для векторных процессоров — это, вроде, факт, не зависящий от того, работал я с библиотекой или нет.
это еще ни о чем не говорит. ради интереса поискал в boost blas, упоминамний о valarray не нашел. зато в нем есть куча своих доморощенных массивов.