LINUX.ORG.RU

Rust и двусвязный список

 , двусвязный список,


4

2

Хорошую тему тут затронули

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

http://contain-rs.github.io/linked-list/src/linked_list/lib.rs.html#11-1388

Или не лучшее? Растаманы и растафобы, собирайтесь на великую битву!

А вот, кстати, ещё про списки:

https://rust-unofficial.github.io/too-many-lists/

★★★★★

Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Потому что наша задача про список с помощью RC вполне себе решается.

Именно. Если от чего-то такого уходить в рамках продуктивного и высокоуровневого языка, так это от «свободных» потоков. Оптимальная модель в этом плане – в JS: воркеры и месседжинг. Когда все выделяемые объекты локальны для потока, RC + анализ циклов делается довольно просто (он и с потоками не особо-то сложный). Да, это в специальных случаях будет медленнее, чем потоки + блокировки. Но блокировки – это очень низкий уровень. Это примерно как ассемблер.

Т.е. фундаментальный вопрос дизайна языка и рантайма – это есть потоки с разделяемыми данными или нет. Если разделяемых данных нет вообще – это один случай. Если их они иммутабельны – другой. Если мутабельны (конкретно, как в Java) – третий. И в каждом случае будет своя система управления памятью. Sweet spot в плане простоты (высокоуровневости) программирования и эффективности – ПСД и иммутабельные данные между потоками.

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

И вот это всё вместе у меня варится-варится - да не сваривается. Например, если мы разрешаем простые ссылки между кучами разных активностей, то у нас всё равно в итоге все кучи склеиваются в одну.

Если делать разделяемые между потоками данные как ПСД, то под капотом это будут деревья, и тут достаточно ARC (с атомиками) без необходимости искать циклы. Локальные для потока данные при этом будут обычно короткоживущими, так что тут хорошо подойдут арены. Например, когда по сети приходит json-запрос, то он парсится в арене, где память выделяется линейно. Эта арена потом удаляется сразу, что относительно быстро.

Т.е. вместо поколенческого GC взять комбинацию ARC для разделяемых иммутабельных данных и арены+пулы для мутабельных короткоживущих сессионных данных.

Поколенческий GC – это, вообще говоря, арена «на стероидах». Потому что каждое поколение – это арена, из которой выжившие объекты переносятся в другую, большую по размерам. Это же определяет то, почему поколенческие GC так быстры на выделении памяти (и поэтому их очень любят сетевые приложения). Выделение памяти происходит в арене.

aist1 ★★★
()
Последнее исправление: aist1 (всего исправлений: 1)
Ответ на: комментарий от aist1

Но блокировки – это очень низкий уровень. Это примерно как ассемблер.

С этим согласиться не готов. Блокировка - это фундаментальный и понятный человеку элемент синхронизации. Другое дело, что система может встать колом и зависнуть. Да, она может. Такова жизнь. Можно лицемерно превратить клинч в livelock, но по сути дела такая система всё равно будет висеть. Т.е. если алгоритм, который по сути дела требует блокировки (проезд машин через перекрёсток) мы заменим на обмен сообщениями (каждый водитель получает поток фотонов от своего светофора, в светофоре колеблется кристалл кварца, посылая сообщения счётчику и т.п.), а при этом на перекрёстке пробка, то семантически такая система всё равно зависнет.

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

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

Например, когда по сети приходит json-запрос, то он парсится в арене, где память выделяется линейно.

Ну как сказать, бывают всякие string pool-ы. Уж не знаю, как там в json, но в лиспе при обмене s-выражениями они во все поля. В этом случае не получается локального выделения для всех данных. Дальше, допустим, захотим мы сделать какую-то трассировку. И нам понадобится отправить какой-то объект в логгер. А объект ссылается на другие объекты. А может быть, нужно объект учесть для статистики, или мы добавили какую-то штуку, которая ищет вредоносные json-объекты. Т.е. легко эту арену «сдувает» и время жизни объектов внезапно удлинняется.

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

Другое дело, что система может встать колом и зависнуть.

Это самая маленькая из проблем. Вообще. Dead/livelock не приводит к тихому повреждению данных, к чему приводят гонки (неогороженный синхронизацией доступ к разделяемым данным) между потоками в том же С++. Потоки – это худший кошмар оптимизатора.

Короче, если ты делаешь низкоуровневый язык, то потоки и блокировки там – это приемлемо. Если же язык высокоуровневый, для прикладного программирования, то нужно что-то типа акторов. Оно будет медленнее, зато безопасно с точки зрения памяти.

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

то под капотом это будут деревья

Ну не, на это я пойтить не готов. Хеш-таблицы очень нужны. Тему с деревьями уже проходили в лиспе.

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

Т.е. легко эту арену «сдувает» и время жизни объектов внезапно удлинняется.

Всё верно. Я просто обрисовываю идею. Проблема «языков с GC» в том, что GC прибит гвоздями к рантаму и дается «как есть». Тогда как комбинация RC, ARC, пулов и арен дает в руки программиста значительно большее пространство дизайна для поиска эффективного решения.

С GC ты не паришься по началу, но начинаешь париться потом, когда GC приходится собирать большую кучу, полную долгоживущих объектов. С RC и аренами ты паришься сразу, зато нет проблем с масштабированием.

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

Dead/livelock не приводит к тихому повреждению данных, к чему приводят гонки

Если данное «атомарно», т.е. меняется за один вызов метода объекта (считая, что каждый поток ассоциирован с неким объектом, а в Обероне это почти так), то ничто не мешает прямо в языке встроить гарантии того, что этот метод вызывается только при условии захваченности этого объекта блокировкой на запись. Как это сделано в synchronized методах в Яве или в sql при высоких уровнях изоляции. Если же действие над объектом составное и кто-то не захватил объект на время всего составного действия, то это уже проблемы в голове разработчика.

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

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

Как будто кто-то не берет блокировку намеренно. Вот забыли её взять, или взяли неправильно. Что делать? Есть thread sanitizer, но в высокоуровневом языке лучше просто исключить весь этот класс ситуаций.

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

Ну тогда у тебя остаются блокировки и шардинг. Они, сами по себе, съедят много времени, так что итоговая производительность твоих хэш-таблиц будет не так, чтобы сильно выше, чем у деревьев.

UPS. Да, еще и lock free. Тоже вариант.

Тут ничего не поделать. Параллельный доступ имеет издержки.

aist1 ★★★
()
Последнее исправление: aist1 (всего исправлений: 1)
Ответ на: комментарий от aist1

Ну не знаю, это надо мерять. Так-то в СУБД исторически в основном деревья используют, но хешированные индексы тоже применяют. Насколько те деревья иммутабельны - я не знаю, но то, что они ради реалтаймовости на лету не балансируются - это, конечно, ужас. Т.е. гарантии по скорости работы с ними весьма посредственные. Не знаю, почему так. Впрочем, и хеш-таблицы нужно перехешировать. В общем, всё плохо.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 2)
Ответ на: комментарий от den73

но хешированные индексы тоже применяют.

У меня тут есть 15 минут, я тебе расскажу, как работают хэш индексы в СУБД.

TL;DR они не многопоточные.

Хэш-индексы создаются на лету исполнителем запроса при загрузке всего отношения целиком в память, так как создание хэш-таблицы очень быстрое (не нужна сортировка, как если строить дерево на лету). Это или маленькие таблички в OLTP случаях, или большие таблицы для аналитики.

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

В общем, всё плохо.

Хороших решений нет. Поэтому мы выбираем те, которые просты в реализации при достаточной эффективности. В этом простое программистское Дао.

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

Ой, это Оракл – своя отдельная Вселенная со своими понятиями. Что они там назвали «хэш-кластером» – это всё другое. На него не стоит ориентироваться.

Я тебе описывал принцип работы обычного хэш-индекса. Это легковесная структура данных, которая создается на лету при чтении таблиц во время выполнения запросов.

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

Тут даже на уровне прагматики можно глубоко закопаться))

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

Так по-моему, Оракл - это самое правильное. Правильный подход к версионности. Но так-то вообще и постгрес туда же:

https://postgrespro.ru/docs/postgresql/9.6/indexes-types

PostgreSQL поддерживает несколько типов индексов: B-дерево, хеш, GiST, SP-GiST, GIN и BRIN

Правда, хешированные индексы у них как-то недопилены. Но они есть.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Или не решили.

Так вот и получается, что отказались от GC, наделали костылей, ходить неудобно,

Ты это, определился бы. Решили, но ходить неудобно или не решили. Или одновременно и не решили и ходить неудобно стало?

Хотя, конечно, самым цимесом было бы предъявить пример этого самого «не решили».

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

Тут главное - вовремя остановиться и искать не «идеальный», а «прагматичный».

Тут, понимаешь ли, кто-то месторождения угля ищет, кто-то — золота, а кто-то — филосовский камень.

Прагматично тут будет притащить в язык все возможные варианты указателей (включая gc-шные) и как-то наладить между ними взаимодействие.

a--
()
Последнее исправление: a-- (всего исправлений: 1)
Ответ на: комментарий от den73

Ты неплохо сформулировал, но я не буду комментировать. Это - не клевета благодаря условной формулировке, но инсинуации.

Я могу и прямо сформулировать. Собственно приглашение к срачу ты прям в этом сообщении и написал. И последующие сообщения от тебя в том же ключе, каждый раз как кто-то напишет «на расте нельзя» ты тут как тут, мол «так и запишем, раст не может».

Я разве делал такое утверждение?

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

Какая ссылка, блин? Худшее время добавления в твой массив - O(N), в то время как худшее время добавления в настоящий список - O(1).

Ну как сказать. Вот на первом курсе, когда нам кстати не сказали, что списки - это структура больше теоретическая, на практике непригодная, нам рассказывали про методы сортировки. Про то что доказано, что сортировка, основанная на попарном сравнении, не может быть быстрее чем O(Nln(N)). И даже предложили такой метод сортировки, heapsort. Гарантированные Nln(N). А на следующей лекции разобрали quicksort. И честно сказали, что его сложность в худшем случае - O(N^2). Но всё равно, он быстрее чем хипсорт. Такой вот парадокс. O-большое - это не мера скорости алгоритма, а указание, как он масштабируется. Так и со списками. В теории да, O(1), Но этот O(1) на практике немного дороже выходит чем O(N). Что легко проверить самому.

Что ещё нужно тут объяснять? Это вопрос школьного уровня. Нужно быть полным идиотом или отмороженным пропагандистом, чтобы ещё после этого упираться.

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

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

Хотя, конечно, самым цимесом было бы предъявить пример этого самого «не решили».

... и при этом еще с условием, чтобы это «не решили» было по свойствам похоже на двухсвязный список, каким он был при Николае I в ХХ веке.

Ну вот например такие условия на коллекцию:

1. Быстрое нахождение первого соседнего элемента перед итератором / после итератора

2. Быстрая вставка элемента перед итератором / после итератора

3. Быстрое удаление элемента по итератору / перед итератором / после итератора

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

Т.е. если у нас 10М элементов и на каждый заведено по итератору, и мы вставили в случайные места 10 новых элементов, то затраты времени должны быть примерно 10, а не 10М и не 3К.

5. Специально, чтобы растаманам жизнь медом не казалась: стабильные итераторы на голову и хвост, обновление которых тоже пропорционально количеству вставленных/удаленных элементов (а можно и сильно быстрее, но мне пока что не ясно, насколько это можно сделать быстро).

Варианты реализации:

А. написать «с нуля» без unsafe

Б. написать без unsafe, используя как данность какую-то структуру данных раста, внутри которой unsafe

Какие есть мысли по этому поводу?

a--
()
Последнее исправление: a-- (всего исправлений: 5)
Ответ на: комментарий от khrundel

одно дело - разница между N Ln(N) и N^2, а другое - между 1 и N.

Но этот O(1) на практике немного дороже выходит чем O(N). Что легко проверить самому.

Не выходит и даже проверять нечего.

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

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

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

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

Собственно приглашение к срачу ты прям в этом сообщении и написал.

Битва - это не обязательно срач. Это может быть, представь себе, битва идей по честным правилам, а не обязательно кто лучше преуспел в придумывании обзывалок и прочих «полемических приёмах».

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

ЛОЛ :)

Ну это совсем уж низко. Решение твоей задачи я тебе дал, вместе с индексами. И даже, так сказать, весь путь к её получению показал, начал без индексов, потом расширил до любого количества индексов. А ты всё что смог - вырвать цитату из контекста и включить дурачка.

Мне вот что интересно, о чём ты вообще думал, когда эту задачку задавал? Нет, я понимаю, ты хотел что-то сложное, поэтому заказал быструю вставку, быстрый поиск, и ещё дополнительно чтоб обход в порядке возрастания и быстрый поиск любому из 2х ключей. Вообще, есть такое эмпирическое правило, «0, 1 или много», так что 2 ключа мало отличаются от «любое количество ключей», но интуитивно их как бы всего 2, всего на 1 больше чем 1, что за проблема.

Как можно было подходить к решению? Какой нам нужен контейнер, чтоб быстро искать и выводить в порядке возрастания? Их в общем 3. Либо сортированный массив, либо двоичное дерево, либо b-tree. Может есть и больше, но вот эти 3 общеизвестны. Про двоичное дерево мы уже знаем, что оно - говно и даже не стоит рассмотрения, отсортированный массив пригоден для относительно быстрого поиска, но плохо переносит вставку, остаётся b-tree. Видишь, нет даже какого-то глубокого вариативного анализа, идём по прямой исключая все очевидно непригодные варианты. Итак, у нас б-дерево, которое по сути массив из массивов (из массивов*N). Ну ок. Вот, у нас уже есть обход в порядке возрастания и поиск по одному ключу. Думаем, как присобачить второй. Не, ну теоретически второй индекс можно построить и на хэшах. Ты же не давал требования сортированного вывода по второму ключу. Получится multimap<key2, key1>. Но это потребует после поиска в индексе по key2 потом искать по key1, что не очень-то эффективно. Да и какая-то переусложнённая хрень получается, один ключ должен поддерживать больше/меньше, второй почему-то хэширование и равенство/неравенство, некрасиво это. Хрен с ним, делаем b-tree и для индекса. И заодно избавляемся от второго лукапа, храним данные в массиве, а поиск по делаем через один из 2 (или любого другого количества) b-tree. Добавление в конец вектора в среднем быстрое. Получаем решение. На чисто безопасном расте. Ну нужно будет немного раскланяться, добавить refcell, непривычный по другим языкам, но в остальном просто.

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

каждый раз как кто-то напишет «на расте нельзя» ты тут как тут, мол «так и запишем, раст не может».

Так ты же сам говоришь, что двусвязные списки не нужны. Не потому ли они не нужны, что «раст не может»? Или ты станешь утверждать, что «раст может»? Тут факт налицо, имею право его записать. Разжигания тут нет, а что кому-то обидно, что он не в ту секту записался - так это может вести к вразумлению божественному.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от khrundel

А ты всё что смог - вырвать цитату из контекста и включить дурачка.

я смог понять, что дальше читать не обязательно. Ты думаешь, я тут всё читаю, что ты пишешь? Нет, я давно сделал выводы на счёт себя и сэкономил кучу времени. Чтобы я начал воспринимать тебя всерьёз, нужно сначала перестать выдвигать тезисы о том, что O(N) быстрее, чем O(1)

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

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

Давай мы лучше выкатим требования к структуре данных, а не к хрюнделю? Типа моих вот: Rust и двусвязный список (комментарий)

a--
()
Ответ на: комментарий от a--

Ты забыл добавить «и чтоб в названии непременно list был».

Слишком переусложняешь, имхо. Достаточно было 1 пункта:

  1. Чтоб можно было хранить 100500 итераторов и они не протухали при модификации коллекции.
khrundel ★★★★
()
Ответ на: комментарий от khrundel

Ты забыл добавить «и чтоб в названии непременно list был».

С этим даже эйчарка справится, так что это не обязательно.

a--
()
Ответ на: комментарий от a--

Да пипец нерешаемая задача про двусвязный список. Его сила в том, что ты можешь отдать клиенту ссылку на элемент и от неё клиент сможет плясать. Тогда вставка даже в середину списка будет O(1). Но проблема в том, что если у тебя вчера был элемент списка, то завтра он может перестать им быть, например, благодаря удалению диапазона. Поэтому такой список, чтобы быть безопасным, должен иметь указателя на сам объект «список» в каждом элементе, и при каждой модификации этот указатель нужно обновлять. И тогда это уже не двусвязный список, а нечто иное. Или нужно как-то ещё гарантировать, что на момент попытки действия над элементом списка мы будем точно знать, находится ли элемент в списке или нет. Но я такого себе даже представить не могу (в смысле статического доказательства).

Я для себя вывод сделал такой, что я попробую проработать сочетание RC + GC, как это уже сделано в Питоне. И соответственно дальше мне уже неинтересно выяснять, как это делается на Расте. Вариант создавать структуры данных на «unsafe» подъязыке, который может промазать мимо памяти, меня совершенно не интересует. А элементы Раста в Обероне уже и так есть, там есть var параметры, которые чем-то похожи на времена жизни в Расте (хотя не полностью, но всё же как-то похожи).

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 4)
Ответ на: комментарий от den73

одно дело - разница между N Ln(N) и N^2, а другое - между 1 и N.

Ещё раз, медленно, для тупых: я уже на практике доказал что вставка в вектор существенно быстрее. Можешь сидеть, плакать, причитать «но ведь O(1)», однако список не может догнать вектор даже при размере коллекции в несколько гигабайт. Можешь надеяться, что на петабабайтных размерах таки список развернётся, ага.

Ну и ты, конечно, не прав. Когда дело касается понятия О-большое, разница между O(1) и O(N) такая же, как между O(N) и O(N^2). Это значит, что при увеличении размера вдвое необходимые ресурсы для первого алгоритма вырастут вот так, для второго в 2 раза больше. Множитель ln(N) пренебрежимо мал, так что имеем практически ту же ситуацию.

Не выходит и даже проверять нечего.

Фанатик, что с тебя взять.

khrundel ★★★★
()
Последнее исправление: khrundel (всего исправлений: 1)
Ответ на: комментарий от den73

Какие-то ограничения на инвалидацию итераторов я не включил в требования, специально чтобы оставить поле для разных решений.

Но по-моему там вполне можно все утрясти, в том смысле что удаление элемента из коллекции не является удалением элемента вообще. К примеру, при попытке найти prev/next от выпихнутого из коллекции элемента кидается исключение (либо просто проверяется такая возможность).

Т.е. все максимально близко к обычному списку, где выпихавние — это обнуление полей prev/next.

a--
()
Последнее исправление: a-- (всего исправлений: 1)
Ответ на: комментарий от den73

Элемент за это время могли не просто удалить, а вставить в другой список.

Можно попробовать потребовать и это. То есть prev/next должны уже давать итераторы на соседей в другом списке.

Но вопросы с удалением/инвалидацией обычно сложнее, чем просто перенос в другое место.

a--
()
Последнее исправление: a-- (всего исправлений: 1)
Ответ на: комментарий от khrundel

Слишком переусложняешь, имхо.

Я всеми силами пытался косплеить список.

a--
()
Ответ на: комментарий от den73

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

Не нужны. Причём на любом языке.

Не потому ли они не нужны, что «раст не может»?

Тебе, дураку, уже 10 раз объяснили, что раст может. Вот элементарно, даже никакой ансейф не нужен. Это обобщённый граф на указателях на Расте построить сложно, из-за потенциальных циклов и необходимости упорядочения вершин, а двусвязный список- он сам по себе упорядочен, так что элементарщина. Как-то так:

struct Node {
    // ...
    next: Rc<RefCell<Node>>;
    prev: Week<RefCell<Node>>;
}

Но тебе хоть кол на голове теши, твоя позиция в этой теме: «я - дурачок и теперь попробуйте докажите мне что-нибудь».

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

я смог понять, что дальше читать не обязательно.

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

Чтобы я начал воспринимать тебя всерьёз, нужно сначала перестать выдвигать тезисы о том, что O(N) быстрее, чем O(1)

Ну, это от того что ты просто не знаешь, что означает запись O(x). Википедию прочитал бы что ли.

Я одного не понимаю, зачем ты торгуешься? Если я такой плохой и пишу глупости, зачем требовать от меня согласиться с твоим утверждением? Тем более что тебе нечего предложить мне, я что называется с открытым забралом, сделал утверждение и его доказал, причём не ковырянием в носу, а бенчмарком. Это ты забился в угол и долдонишь «а я не буду проверять, и так я никогда не узнаю, что написал глупость».

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

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

Как правильно заметил eao197, ты тут (сейчас) один против всех.

Поэтому я предлагаю тебе не размениваться на мелочи, поскольку после того, как ты отобьешь первые неудачные атаки на раст (а ты их уже практически отбил), начнутся более серьезные. И более интересные.

Причем я буду стараться, чтобы это были атаки не с новых позиций, а именно со старых. Ну может чуть-чуть подвинувшись.

a--
()
Последнее исправление: a-- (всего исправлений: 5)
Ответ на: комментарий от khrundel

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

Если я такой плохой и пишу глупости, зачем требовать от меня согласиться с твоим утверждением?

Да не соглашайся, мне-то пофиг. Я всего лишь объясняю, при каких условиях может начаться разговор по существу. Ты этих условий не хочешь соблюдать, поэтому и разговора не будет, а так можешь оставаться при своём мнении, которое из серии рассказов про плоскую Землю. ,

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

Так по-моему, Оракл - это самое правильное.

Oracle – MVCC, но не Copy-on-Write. Он всегда обновляет текущую версию, что позволяет не трогать индексы, просто делает UNDO log для предыдущих версий.

aist1 ★★★
()

Почитал тред, всё понял.

Oldboy
()
Ответ на: комментарий от a--

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

Нет. Я трачу именно на технические моменты. Я объяснил местному народу как делается обобщённый орграф, походу реально мало кто задумывался над тем, можно ли создавать его на указателях и какими проблемами это чревато. Я открыл глаза на существование deque. Люди видимо не знали про кольцевые массивы и реально думали, что если нужна вставка с обеих сторон то ничего кроме листа им не подходит. Даже «базу данных» для нашего друга денчика я создал. А в ответ клоуны пишут какой я глупый, потому что им в школе что-то объясняли про O(x), они не так поняли и вот это детское впечатление для них так свято, что им 1 уже готовый бенч запустить влом. Ну да, таким я уже помочь не могу.

Как правильно заметил eao197, ты тут (сейчас) один против всех.

Так ветка растосрачная и даже без какой-то интересной идеи. Создана исключительно с целью доказать, что раст - говно. Нормальные люди сюда просто не заходят. Поэтому никаких удачных атак тут не будет, чтоб их произвести нужно немного пощупать раст, узнать как с ним работают.

Уверен, что тот же Денчик, например, даже не знает о такой вот особенности раста:

let mut value: T = // ...
let mut arr: [T, 10] = //...

value = foo(value); // работает
arr[0] = foo(arr[0]); // ошибка компиляции

иначе он бы создал ветку и про неё.

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

А книжку, которую сам же привёл в шапке, ты удосужился прочитать? Хотя бы первую главу. Судя по твоим высказываниям - нет, не удосужился. И это прекрасно говорит о твоей вменяемости. Просто взгляд со стороны. Прочитал всю тему. И вижу, что ты реально в ней плаваешь, несмотря на попытки khrundel тебя вразумить. Мало того, что плаваешь, ещё и вникать не желаешь, что уже является симптомом о том, что разговор по существу с тобой в принципе невозможен.

DyadyushkaAU
()
Ответ на: комментарий от alysnix

область видимости, это список обьектов декларировнных в данной области, это есть список. у вас в конструкторе - размер списка… какой размер ставить в данном случае?

Я ооочень сомневаюсь, что список это подходящий тип данных и в данном случае и вообще. То что понимают под списком в программировании это НЕ список условно говоря объектов. Это в 99% случаев массив. В списке смысл появляется только в том случае, когда связь между членами списка должна меняться. 1. 2. 3. итд это только в народном понимании список. в реальности это массив данных.

И раз это массив данных, то ответ на Ваш вопрос идентичен ответу на вопрос о размере массива когда окончательный размер не известен и число членов растёт со временем. Если хотите на этот вопрос ответ даёт std::vector. Т.е. начальное число может быть хоть 0. Но постепенно оно растёт. Используя статистику можно начать с некоторого числа N, которое в 90% случаев будет достаточным, чтобе не выделять память каждый раз.

ваше творение будет пожирать память просто так

Разумеется НЕТ. Вы как будто с луны свалились. Откройте книжку и почитайте про std::vector…

P.S. Нельзя задавать такие вопросы. Они слишком много говорят о том, кто спрашивает…

lefsha
()
Ответ на: комментарий от khrundel

Необязательно, есть безразмерный слайс.

НЕТУ! Это НЕ самостоятельный тип данных. Вы говорите о том, чего не понимаете!

но если нужно, то делают через создание и заполнение вектора

Боже… Жуть то какая… Человек даже не понял что такое вектор. Нафига делать из вектора slice, если УЖЕ есть вектор? Что мне даёт slice, чего мне НЕ дает вектор?

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

Правда состоит в том, что есть статический массив в стеке и динамический массив в «куче». И это все массивы - array.

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

И по своей структуре гораздо более похожий на тот самый список. Всякие там push_back() и pop_back() собственно в массиве НЕ имеют смысла. Массив это кусок памяти с произвольным доступом изначально, который можно распараллелить - обрабатывать 2+ ядрами.

И вот вместо этого естественного типа данных мне предлагают урезанный статический массив и вектор, который массивом НЕ является. Его можно сделать таковым, но зачем?

Это деградация языков программирования? То что делается в С одной строкой становится проблемой чуть ли не во всех других языках.

Т.е. мне предлагают в замен тормоза и извращения. Ну это как-бы не очень себе выбор…

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