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)

Ответ на: комментарий от byko3y

Тем временем шла середина 2022.

«C’mon man, its 2k22» - это, конечно непобедимый аргумент, ага. И универсальный.

чтобы не применять GC — хотя GC бывает быстрее подсчета ссылок.

Только в особых случаях и когда RC не поддерживают мув. В расте поддерживают.

Однако проблема GC не только в плохой производительности. Проблема в том, что GC проблему менеджмента ресурсов решает никак. GC решает одну небольшую подзадачу, освобождения памяти, на которую не осталось ссылок. Задачу, которая, если верить твоим словам о избытке мощности, вообще не существует. В самом деле, если некуда девать производительность процессора, то с памятью-то и того проще. Чтоб увеличить производительность главного потока (ты утверждаешь, что именно он ограничивает) в 2 раза нужно ждать лет 5-10 новых процессоров, а память можно хоть учетверить, просто сходя в магазин. А ещё есть своп. Т.е. можно тупо писать без GC, ну перезапускать процесс раз в сколько-то дней.

Но вот работу с файлами, например, никак GC не контролирует. Даже не смотря на всякие финализаторы и фантомные ссылки. В итоге java, не последний язык и не маргинальщина какая-то, на 20 году своего существования получает некое подобие RAII из «устаревшего» C++. А до этого вообще на уровне классического C был.

Но при этом он не пытается использовать ЦП на полную с помощью «lock-free» программирования,

Ты не поверишь, но есть в CPU такая штука, называется «кэш». Вот она смотрит на тебя с осуждением и говорит, что если ты хочешь использовать на полную мощь, тебе нужно не локфри, а как раз изоляция по данным. В остальном, если появится вменяемая система локфри синхронизации потоков - её через пару месяцев реализуют в очередной либе раста. Раст - это язык не завязанный на какой-то особый рантайм, так что легко заменят. Что останется неизменным, так это система типов, гарантирующая проверки владения.

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

Нет, это в том числе и гарантия, что во время итерирования никто не поменяет массив. Подсчёт ссылок такое не даёт.

Ага, нет потоков — нет проблем. Очень удобно жить в 80-х годах.

Как нет, если есть? Вон же они, в std::thread. И ты даже сможешь пользоваться ими и твоим двусвязным списком. И даже сможешь пользоваться твоим списком внутри потока. И добрый компилятор позаботится, чтоб ты не прострелил себе ногу.

C++ позволял дольше всех игнорировать фундаментальный изъян этой модели — именно поэтому C++ победил в разработке GUI

Ну не знаю… я уже когда писал лабы на дельфи как-то узнал что делать работу в главном потоке не то что бы хорошо. Даже на уровне лабы изъян как-то не игнорировался. Получается, если ты считаешь, что именно гуи спас плюсы, а я знаю, что в гуёвом потоке толком не поработаешь, то получается что всё хорошо у «языков из 80х» с многопоточкой, ну либо с кооперативной конкуренцией.

И тут выходит раст, у которого ещё лучше.

ЦП Тьюринга нет и быть не может. Оно небезопасное и всё тут. Ты либо дольше разрабатываешь, либо теряешь производительность, либо теряешь надежность — что-то произойдет. Я сам недавно на LOR-е писал, что наклевывается что-то такое, но по итогу я не вижу никакого света в конце тонеля — слишком высока комбинаторная сложность.

Это до тебя, но немного в другой области, обнаружили сам Тьюринг в виде проблемы остановки и Дейкстра так же заметил проблему комбинаторики. И тогда Дейкстра написал своё «гото консидеред хармфул» и предложил отказаться от «ЦП Тьюринга» и писать нормальные циклы и ветвления. Внезапно оказалось, что несмотря на то, что программа для машины Тьюринга, в общем виде, не поддаётся анализу, но пара абстракций внезапно делает задачу на порядок проще. И что-то не видел я давненько рассказов о том, что вот на гото можно такого классного написать, оказалось что и ветвлений/циклов оказывается достаточно.

Я уже раза два писал, что лайфтаймы и владение — это едва ли половина всех проблем низкоуровневого кодинга. А в высокий уровень Rust не умеет.

Как не умеет? Функциональное программирование же. Этот мифический «высокий уровень» нам обещают уже полвека, про языки управлениями потоками данных, которые сами всё сделают, им только объясни что тебе надо. А потом пишешь на sql запрос, мало того что простейшие задачи приходится кучей копипасты решать, так ещё и в процессе выясняется, что where s.column1 = foo('bar') выполняется очень долго от того что функция foo как-то не так объявлена, что СУБД не догадывается, что не нужно её заново вызывать на каждой строке.

Многопоточка Clojure — космос по сравнению с растом.

Почитал. STM. На мой взгляд - типичный лохотрон для дурачков. Вообще, похоже ты страдаешь синдромом «пусть кто-то другой сделает мне серебряную пулю». То волшебный GC, который ещё в 70х был так хорош, так хорош. Настолько, что в 2022 и бедная jvm просматривает код, занимается «анализом побега» ради того чтоб обнаружить объекты, которые можно безопасно создать на стеке, а программисты передают в функцию массивчик для заполнения, ну чтоб чтоб заново не выделять.

Теперь вот очередной продавец змеиного масла говорит о волшебных транзакциях, которые сами разрулят все проблемы. И даже локфри (*может быть когда-нибудь). Проблема в том, что кложа, судя по описанию, так же решает проблему многопоточки путём запрета расшаренного изменяемого стейта для основной рабочей памяти потока, а для вот этой волшебной STM у них особая штука, рефы. Что из этого следует? Что ты свой внутренний изменяемый стейт должен меняться за пределами транзакций, либо жить внутри них. И вообще, чем длиннее по времени транзакция, тем больше шансов что она будет перезапущена и больше этой внутренней работы пропадёт. Т.е. в теории и на игрушечных примерах всё круто, а на практике будет вместо растового «считаем, считаем, считаем, заполняем структурку-месседж и отправляем в канал» в ней будет «считаем, считаем, считаем, создаём транзакцию для сохранения результата». А без «считаем, считаем, считаем» никакая многопоточка и не нужна в принципе.

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

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

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

Маленькая ошибка должна приводить к маленьким последствиям. Вот если у тебя половина оперативной памяти отвалилась или кто-то отключил один из процессоров — это серьезная проблема, тут даже можно ронять систему. А один бит/байт у тебя испортится, рано или поздно, что приведет к совершенно любому сбою В машине Тьюринга. Именно это является одним из фундаментальных изъянов данной модели (а вторым — немасштабируемость).

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

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

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

в атомной отрасли и делают три разные, тремя разными командами. Пересекаются они только по ТЗ.

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

чтобы не применять GC — хотя GC бывает быстрее подсчета ссылок.

Только в особых случаях и когда RC не поддерживают мув. В расте поддерживают

Даже без счетчика ссылок менеджер памяти, падла, дорогой. А со счетчиком еще дороже. Чтобы освободить в нем кусок памяти, нужно добавить этот кусок в связанных список или хотя бы установить бит на странице. Более того, GC может устранять фрагментацию, чего толком не умеет делать ни один менеджер памяти. Да, есть решения вроде Hoard, которые хранят блоки близких размеров в одной странице, но побочным результатом такого подхода является false sharing, который в свою очередь вроде как решается thread-local пулами, но срабатывает только при минимизации межпотокового взаимодействия. Я почему и написал «бывает быстрее» — потому что далеко не всегда, но всё же бывает, как бы люди не рассказывали басни про «GC = тормоза».

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

Вот буквально в прошлом моем треде в /development, но про C++, поднимали вопрос того, что C++ тоже не решает проблему управления ресурсов, что задача высвобождения памяти и задача высвобождения ресурсов совершенно независимы и сливаются в одну только на уровне hello world. В полезном же коде функции неизбежно расщепляются на «finalize» и «free». И, как ни странно, функцию free сборщик мусора выполняет лучше. Причем, те же современные hoard и mimalloc на самом деле лежат где-то посередине между менеджером памяти и сборщиком мусора, поскольку у них тоже free меж потоками (а может и внутри, надо смотреть) не приводит к немедленному переиспользованию блока, а лишь добавляет этот блок в очередь на уборку.

В самом деле, если некуда девать производительность процессора, то с памятью-то и того проще

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

В итоге java, не последний язык и не маргинальщина какая-то, на 20 году своего существования получает некое подобие RAII из «устаревшего» C++. А до этого вообще на уровне классического C был

Ты про try-with-resources? Я считаю реализацию RAII в C++ ублюдочной, потому не вижу смысла сравнивать что лучше — говно или моча. Java с самого начала играла в специальную олимпиаду «кто выберет самые провальные аспекты C++».

А до этого вообще на уровне классического C был

Самый ранний Java-подобный прототип — это UCSD Pascal и p-машина, корректнее было бы сравнивать с ними. И Java застряла где-то там, потому что перенятые с C++ аспекты привели ее к серьезной деградации, из которой жаве было очень тяжело было выкарабкиваться. Так или иначе, с Си она почти ничего общего не имеет (кстати, ты палишься своим узким кругозором).

Я уже раза два писал, что лайфтаймы и владение — это едва ли половина всех проблем низкоуровневого кодинга. А в высокий уровень Rust не умеет.

Как не умеет? Функциональное программирование же

Один из столпов функциональщины начиная с сеердины 80-х — это вывод типов насквозь через функции. Ну и где он в расте? Его обрезали как раз там, где он нужен. Второй столп — это хранение данных через замыкания и высвобождение их сборкой мусора. Ну и где оно в расте?

Этот мифический «высокий уровень» нам обещают уже полвека, про языки управлениями потоками данных, которые сами всё сделают, им только объясни что тебе надо. А потом пишешь на sql запрос...

Вообще-то SQL — это конец 70-х/начало 80-х. То есть, еще старее.

То волшебный GC, который ещё в 70х был так хорош, так хорош. Настолько, что в 2022 и бедная jvm просматривает код, занимается «анализом побега» ради того чтоб обнаружить объекты, которые можно безопасно создать на стеке, а программисты передают в функцию массивчик для заполнения, ну чтоб чтоб заново не выделять

Посмотри на опрос на Stackoverflow — 82% отдано за языки с GC. Ой, GC так плох, так плох.

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

Чтоб увеличить производительность главного потока (ты утверждаешь, что именно он ограничивает) в 2 раза нужно ждать лет 5-10 новых процессоров, а память можно хоть учетверить, просто сходя в магазин. А ещё есть своп

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

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

Ты меня с кем-то путаешь. Я давно ссал в лицо локфришникам, которые вяжутся на единственную ячейку памяти. Lock-free не значит, что у тебя обязательно будет разделяемый изменяемый кэш — оно просто не запрещает такого сценария. То есть, если трения меж потоками есть — кэш будет разделяться, если нет, то кэш будет работать как в однопоточке. Это в том числе так называемые «оптимистичные блокировки», хоть и далеко не только они. Все конструкции Rust направлены на то, чтобы разделяемая линия кэша была строго read-only, никакой одновременной записи не допустимо.

система локфри синхронизации потоков - её через пару месяцев реализуют в очередной либе раста

Локфри синхронизация — это оксюморон.

Borrow checker — это в том числе оптимизация для избежания подсчета ссылок вообще

Нет, это в том числе и гарантия, что во время итерирования никто не поменяет массив. Подсчёт ссылок такое не даёт

Дает, только счетчика будет два.

Ага, нет потоков — нет проблем. Очень удобно жить в 80-х годах.

Как нет, если есть? Вон же они, в std::thread

Ты как питонисты, которые рассказывают «есть в питоне потоки, вот же модуль threading». Да, есть, только в питоне они бесполезные настолько, что можно считать что «нет». Да, в Rust ситуация с потоками чуть лучше, но ненамного: пользоваться многопотоками в расте можно, но это будет сплошной unsafe и Си-подобный код.

Ну не знаю… я уже когда писал лабы на дельфи как-то узнал что делать работу в главном потоке не то что бы хорошо. Даже на уровне лабы изъян как-то не игнорировался. Получается, если ты считаешь, что именно гуи спас плюсы, а я знаю, что в гуёвом потоке толком не поработаешь, то получается что всё хорошо у «языков из 80х» с многопоточкой, ну либо с кооперативной конкуренцией

Однопоточный GUI с воркерами в отдельных процессах или даже на отдельных машинах — это хорошо всем известный X Windows, который середина 80-х. Там как бы потоков просто не было вообще в операционной системе, потому не было и синхронизации между потоками. Потому я писал «начало 90-х» — именно в то время поперли NeXTSTEP и позже Win 95 с потоками и дожившей до наших дней моделью GUI, под которую писался Rust.

Кстати да, еще можно запускать тяжелую задачу в отдельном процессе — в винде даже целую инфраструктуру COM для этого сделали. И даже сделали DCOM для удаленного выполнения. Но тут внезапно выясняется, что в 21-м веке нужна еще и готовая развитая координация, а не простой мутекс или синхронный вызов-ответ (TThread.Synchronize).

И тут выходит раст, у которого ещё лучше

Да, который самый такой же, как все до него.

Это до тебя, но немного в другой области, обнаружили сам Тьюринг в виде проблемы остановки и Дейкстра так же заметил проблему комбинаторики. И тогда Дейкстра написал своё «гото консидеред хармфул» и предложил отказаться от «ЦП Тьюринга» и писать нормальные циклы и ветвления

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

Многопоточка Clojure — космос по сравнению с растом.

Почитал. STM. На мой взгляд - типичный лохотрон для дурачков.

«Выучить Clojure за пять минут». Вообще-то там еще агенты и атомы. И между потоками можно передавать не только примитивные данные, но и целые замыкания — расту до этого уровня карабкаться нереально.

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

В кложе можно читать изменяющиеся ref-ы — ты просто не получаешь гарантий согласованности между несколькими прочитанными значениями. А атомы и агенты позволяют изменять разделяемые данные вне транзакций. Там еще и каналы есть с моделью «несколько писателей — несколько читателей».

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

в атомной отрасли и делают три разные, тремя разными командами. Пересекаются они только по ТЗ

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

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

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

Нет, если у тебя не джава с кучей мелких объектов. А мелкие объекты только если ты имел глупость связаться с GC.

А со счетчиком еще дороже.

Нет, если у тебя RC перемещаются. Если копируются - да, ты тупо передаёшь в функцию, счётчик увеличивается, функция передаёт в следующую - ещё увеличивается, и так далее, а потом назад уменьшается. Если сделано нормальное перемещение, это просто копирование 64битного числа, счётчик не трогается. А знаешь где сделано нормальное перемещение? Правильно, в расте.

Вот буквально в прошлом моем треде в /development, но про C++, поднимали вопрос того, что C++ тоже не решает проблему управления ресурсов, что задача высвобождения памяти и задача высвобождения ресурсов совершенно независимы и сливаются в одну только на уровне hello world.

Чё за глупость вы там в твоём треде наковыряли никого не волнует. В RAII любой ресурс (память или не память, неважно), обрабатывается одинаково и на основании того что программист написал. GC ничего подобного предложить не может, он может управлять только количественными и взаимозаменяемыми ресурсами. Если ввиду реализации GC и фазы луны вот этот, давно потерянный кусок памяти, сутками не собирается - да и хрен с ним, выделим другой, главное чтоб общее количество свободной памяти было достаточным. С другими ресурсами… примерно со всеми остальными, это не катит, если тупой GC никак не найдёт время вызвать финалайзер файла разблокировать его (если в системе есть блокировки) или даже просто сбросить данные в буфере на диск, то это совсем другое дело.

Поэтому RAII - вменяемый способ управления ресурсами, а GC - говно.

Самый ранний Java-подобный прототип — это UCSD Pascal и p-машина, корректнее было бы сравнивать с ними.

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

Один из столпов функциональщины начиная с сеердины 80-х — это вывод типов насквозь через функции.

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

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

Как я тебе объяснил выше, GC - говно и не подходит для серьёзного программизма. Давай забудем про него. Итак, есть ли в расте хранение данных в замыканиях и автоматическое освобождение?

use std::thread;
use std::vec;

fn create_func() -> impl FnOnce() -> () {
    let mut v = vec!(1,2,3);
    v.push(4);
    return move||{
        v.push(5);
        println!("in func: v = {:?}", &v);
    }
}

fn main() {
    let func = create_func();
    let th = thread::spawn(func);
    th.join().ok();
}

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

Вообще-то SQL — это конец 70-х/начало 80-х. То есть, еще старее.

Так срань про высокоуровневые языки ещё раньше появилась. SQL появился тогда, как очень крутой язык, и с тех пор развивался, причём не Васяном в свободное время, а умными людьми на зарплатах у крупных корпораций. И я не помню в SQL ни операции new, ни delete, никакой вот этой дрочки памяти, всё как деды из 60х завещали. И вот, в 2022м мы имеем особую квалификацию программистов, которые знают всякие волшебные слова чтобы база не так сильно тормозила, а стековерфлоу переполнен вопросами типа «как сджойнить 2 таблицы чтоб строки первой не дублировались и выбиралась строка второй с максимальным третьим полем».

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

Посмотри на опрос на Stackoverflow — 82% отдано за языки с GC. Ой, GC так плох, так плох.

Если смотреть кто на чём работает, то js будет первым во всём. При этом про его кривизну мемчики пишут. Люди работают на том, на чём приходится. В 60м стековерфлоу бы показал крутизну ассемблера.

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

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

Извини, тег «сарказм» не поставил. Я над тобой смеюсь. Ты пишешь, что CPU так быстры, что нефиг GC бояться. Я тебе ответил в том же духе: незачем нам GC, тупо выделяем память, не освобождаем, а если мало - докупить. Ну а насчёт «не быстрее» - так ты же сам писал, что нефиг эти такты считать, и так избыток.

Локфри синхронизация — это оксюморон.

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

Ты как питонисты, которые рассказывают «есть в питоне потоки, вот же модуль threading».

В расте есть и потоки, и есть защита от выстрела себе в ногу. Вообще, у тебя в голове то ещё говно. Вот ты придумал себе двусвязный список, и чтоб он у тебя быстро работал, ты наколхозил его на однопоточных компонентах. Никаких локов, никаких локфри-технологий ты не использовал. И раст позволяет тебе использовать этот список в многопоточной программе, позволяет использовать такие списки в любых потоках и даже следит, чтоб каждый использовался в своём. Что тебе ещё надо? Что он должен был бы сделать, чтоб твоя душенька была довольна? Переписать беспалева на Arc<Mutex>?

Однопоточный GUI с воркерами в отдельных процессах или даже на отдельных машинах

Мы говорим о примерно 99% гуёвых программ. Какие нахрен отдельные машины? Ты в сраном текстовом редакторе давно видел чтоб при запуске поиска в файле всё зависало (а в windows до 386 вытесняющей многозадачности вообще не было, так что виснуть должна была вся система).

Это не имеет отношения к многопоточности-многозадачности, это метод снижения наблюдаемой сложности у однозадачного алгоритма

Ля, ну ты тупой. Проблема у тебя и у Дейкстры была одна и та же: «машина Тьюринга», которая принципиально не поддаётся анализу. И вот Дейкстра на твоём месте подумал и понял, что вместо того чтоб пытаться проверять любую программу, нужно лишь выделить набор абстракций, достаточный для решения задач, которые при этом просто понимать и проверять. И предложил пользоваться ими. А ты пошёл другим путём, тебе даже выдали те самые абстракции, которыми можно пользоваться чтоб не заблудиться в многопоточке, но ты их выбрасываешь и говоришь что нет, абстракции плохие, надо делать всё через жопу. И даже после того как я 3 раза тебе объяснил, что не так с твоим подходом, ты так походу и не понял о чём тебе говорят.

«Выучить Clojure за пять минут». Вообще-то там еще агенты и атомы.

Знаешь, а мне насрать. Я слишком стар чтоб изучать очередной говноязык от Васяна. Если Васян сам написал, чем его язык хорош в решении задачи многопоточности (изолирование данных + STM для shared mutable), то я верю Васяну и критикую его говноязык на основании им же предложенных решений. Если там где-то у него есть атомы, или даже на всякий случай и мутекс припасён, что мне с этого?

В кложе можно читать изменяющиеся ref-ы — ты просто не получаешь гарантий согласованности между несколькими прочитанными значениями.

Да ты что? А теперь посмотри что я написал ниже процитированного тобой куска.

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

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

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

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

А мелкие объекты только если ты имел глупость связаться с GC.

Не вижу связи.

Поэтому RAII - вменяемый способ управления ресурсами, а GC - говно.

Но ты пишешь это на лоре. На бекенде у него ява, а на фронтенде - js.

GC - неработоспособное говно в любом случае

Жир потёк с монитора.

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

GC управляет только памятью. Ресурсами, такими, как файлы, можно управлять с помощью раскрутки стека, так же, как это делается в С++. Просто в С++ зачем-то это приделано к объекту, хотя никто не заставлял. Странно, что это приходится писать, вроде простые и довольно общеизвестные вещи.

Нет, если у тебя RC перемещаются.

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

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

Нет, если у тебя не джава с кучей мелких объектов. А мелкие объекты только если ты имел глупость связаться с GC

Пф-ф-ф, уже забыл, как раст создает контейнеры с одним-двумя полями на каждый чих? И с однострочными геттерами-сеттерами. Rust прежде всего не получилось бы реализовать в начале 90-х потому, что у него даже hello world бы еле ползал без оптимизаций. Эту черту Java приобрела именно от C++, ремейком которого является Rust.

Нет, если у тебя RC перемещаются. Если копируются - да, ты тупо передаёшь в функцию, счётчик увеличивается, функция передаёт в следующую - ещё увеличивается, и так далее, а потом назад уменьшается

Если у тебя счетчик, то ты как минимум один раз его увеличиваешь-уменьшаешь. А скорее всего даже не один, иначе бы ты не использовал счетчик. А изменение счетчика — это не просто одна запись в память, это еще и cache-miss, если ты не поменял также соседние данные (тогда cache-miss общий и неизбежен). GC позволяет вообще не трогать read-only данные.

Это, к слову, причина провала модели GC в питоне, который не просто трогает read-only данные — он это делает при каждой сборке мусора. Из-за чего fork в питоне тупо бессмысленен, даже несмотря на то, что поддерживается.

А знаешь где сделано нормальное перемещение? Правильно, в расте

Традиционный аргумент растовиков «а вот в крестах еще хуже», только без явного упоминания крестов, будто кроме крестов ЯП не существует. Хотя даже в крестах уже есть move semantic, пусть оно и настолько ублюдочное, что мало кто им пользуется без необходимости. Частичная оптимизация передачи ссылок есть даже в питоне, в сраном тормознутом еле ползающем питоне — чем ты собрался хвастаться?

Чё за глупость вы там в твоём треде наковыряли никого не волнует. В RAII любой ресурс (память или не память, неважно), обрабатывается одинаково и на основании того что программист написал

А наковыряли то, что «любой ресурс» недопустимо считать любым: память, на которую есть жесткие ссылки, недопустимо высвобождать где попало и как попало. Именно это и есть провал крестовой модели RAII, от которой отказались в том же Go в пользу явного defer для ресурсов и GC для простой памяти (в том числе массивов). И вот сразу замечательный пример, почему Rust никуда не убежал от этой проблемы:
https://docs.rs/binary-tree/latest/src/binary_tree/lib.rs.html
Да, вроде как Node можно реализовать на Box или счетчиках ссылок, в том числе copy-on-write (идут в комплекте), но сама реализация дерева крутит указателями и временем жизни вручную. Например, если элемент дерева ссылается на само дерево (самый простой варик, бывает сложнее), то это приезд на утечку. Никогда такого не было — и вот опять память нужно высвобождать руками.

Именно потому RAII не масштабируем, в отличие от GC. Адепты Rust апеллируют к тому, что можно сделать unsafe реализацию контейнера с safe интерфейсами — но я только что привел пример того, что поверх этого всего придется делать еще один слой приседаний. Пардон, а какой вообще тогда был смысл этой олимпиады с safe/unsafe? Чтобы hello world-ы были красивые, или чтобы не париться о памяти при росте приложения? Индустрия свой выбор сделала и пишет на GC — чтобы не париться о памяти при росте приложений, вместо того, чтобы 5 дней в неделю безостановочно тренироваться в приседаниях.

Если ввиду реализации GC и фазы луны вот этот, давно потерянный кусок памяти, сутками не собирается - да и хрен с ним, выделим другой, главное чтоб общее количество свободной памяти было достаточным

Охохо, наивность, не слышавшая про фрагментацию памяти. У самого-то, наверное, в растовом коде неделями висят страницы с 10% заполнением, и норм.

Слушай, давай ты свои энциклопедические знания при себе придержишь

Вот поэтому ты искренне считаешь, что прикасаешься к чему-то девственно свежему, а не к древнему засохшему говну, которую пускают уже по десятому кругу. Идею строгих указателей формулировал в то время сам Вирт (70-е годы, ололо), но для компьютеров того времени она была просто неподъемна, потому аж до 90-х годов никто даже не пытался сделать подобную реализацию.

Как я тебе объяснил выше, GC - говно и не подходит для серьёзного программизма. Давай забудем про него. Итак, есть ли в расте хранение данных в замыканиях и автоматическое освобождение?
let func = create_func();
let th = thread::spawn(func);

Argumentum ad Hello Worldum. Мне это до боли напоминает историю с C++, где после того, как самому тупому программисту становится очевидна ограниченность инструмента на масштабе в 400 строк, создается костыль, который позволяет сделать еще один маленький шажок до 4000 строк, и снова упереться в ту же стену. Взаимные ссылочки замыканий где? Да хотя бы и обычные ссылочки? Ты же передаешь просто значение — этот код можно переписать на Си с минимальными изменениями в виде явного конструктора структуры-замыкания.

К слову, это и есть истинная природа borrow checker-а: чтобы написать так же, как это можно было бы сделать на Си, только имея чуть больше гарантий. Проблема в том, что сложносвязанные структуры в Си очень сложно описывать — как их сложно описывать и на Rust-е.

SQL появился тогда, как очень крутой язык, и с тех пор развивался, причём не Васяном в свободное время, а умными людьми на зарплатах у крупных корпораций

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

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

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

На самом деле я даже не знаю ни одного современного решения для поточной обработки данных — все имеющиеся гоняют то же говно по десятому кругу, а реально годные приходится писать почти с нуля, будь то под CPU, GPGPU, или FPGA.

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

Уже давно неактуальные. Крокфорд пришел — порядок навёл.

В 60м стековерфлоу бы показал крутизну ассемблера

Ага, «не историк». В 60-м почти все языки были ассемблероподобные, включая кобол, фортран, бейсик, то есть, с goto на все случаи жизни и без локальных переменных. Более того, продвинутые ассемблеры конца 60-х были мощнее, чем Си (и потому плохие, на самом деле). Исключением был Алгол-60, от которого в той или иной степени произошли почти все современные ЯП, но понадобилось дофигища десятилетий, чтобы умертвить убедить старперов в том, что структурное программирование, локальные переменные, и рекурсия — хорошие идеи.

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

Извини, тег «сарказм» не поставил. Я над тобой смеюсь

Я отвечаю на то, что ты пишешь, а не на то, что ты думаешь — libastral у меня устаревшей версии, сорян.

Ты пишешь, что CPU так быстры, что нефиг GC бояться

Не писал я такого. Я писал, что GC так быстро, что не является помехой. Еще не писал, но тормознутость жавы не связана с GC — это просто максимально убогий язык, спроектированный манагерами.

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

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

По поводу lock-free я уже ответил — нет более-менее универсальных алгоритмов/абстракций, нужно каждый раз писать руками, к сожалению. А значит, в расте этого не будет, бг-г-г.

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

Я? Зачем он мне нужен?

И раст позволяет тебе использовать этот список в многопоточной программе, позволяет использовать такие списки в любых потоках и даже следит, чтоб каждый использовался в своём. Что тебе ещё надо? Что он должен был бы сделать, чтоб твоя душенька была довольна? Переписать беспалева на Arc<Mutex>?

Да, вот именно, тебе придется использовать либо ссылки с блокировками, либо lock-free, вроде RCU, реализация которого в Rust пока что выглядит вот так:
https://github.com/jeehoonkang/rcu-rs/blob/master/src/lib.rs
При том, что у меня в PSO в чистом user-space уже реализованы сложносвязанные структуры с quiescence-based reclamation, что есть более сложный, но и более универсальный инструмент. Удачи сойти с ума, реализовывая что-то подобное на Rust, или «забудь про RAII всяк сюда входящий».

Ты в сраном текстовом редакторе давно видел чтоб при запуске поиска в файле всё зависало

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

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

Да, на что я ответил, что абстракции эти чудовищно куцые и не годятся для задач, выходящих за рамки написания браузера по модели начала 90-х годов (когда Netscape Navigator и был создан). Ровно так же подход структурного программирования на самом деле тоже очень куцый, он совсем никак не помогает писать многозадачные программы. ты бы еще сказал «вот же есть SQL — зачем тебе JavaScript». У них разные задачи! Это не серебрянная пуля, а компромисс. Не умеет Rust в lock-free и сложносвязанные данные, не спроектирован он под них, но главный цикл GUI на нём писать приятно — такой компромисс приняли разработчики раста.

Я слишком стар чтоб изучать очередной говноязык от Васяна

Но Rust-то ты выучил? А он ведь примерно такой же нишевый, как и Clojure.

Если Васян сам написал, чем его язык хорош в решении задачи многопоточности (изолирование данных + STM для shared mutable), то я верю Васяну и критикую его говноязык на основании им же предложенных решений. Если там где-то у него есть атомы, или даже на всякий случай и мутекс припасён, что мне с этого?

Одна из первых ссылок с сайта васяна:
https://clojure.org/about/concurrent_programming
Я о том, что ты каким-то образом умудрился покритиковать инструмент, почти ничего не зная про него.

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

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

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

Не вижу связи.

Ну подумай. Создай простейший класс, например Point2d. Потом сделай из него другой класс, например Triangle. Или просто создай и заполни массивчик объектов этого класса. Сравни с тем, как это делается в плюсах/расте.

Но ты пишешь это на лоре. На бекенде у него ява, а на фронтенде - js.

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

GC управляет только памятью.

Да. И я объяснил почему.

Ресурсами, такими, как файлы, можно управлять с помощью раскрутки стека

А что, память - это уже не ресурс? Да и не любой памятью GC управляет. Всякие буферы для JNI внезапно тоже становятся управляемыми вручную ресурсами. И что, ресурсы разве недостойны такого же удобства, как и память? Почему я могу выделить массивчик и раскидать по программе ссылку на него, а ссылку на файловый дескриптор не должен, а наоборот, обязан обернуть его в try with resources?

Вы ставите телегу впереди лошади. Это не какое-то особое требование к управлению памятью, которое потребовало изобрести GC именно для этой области, это недостатки GC потребовали вывести из под него управление всеми другими ресурсами. А потом возникают всякие интересности. Вот, скажем, есть у меня дерево классов, хранящих, ну например картинки разные. И управляются они GC. А потом возникает желание добавить класс для изображения в буфере графического API. И всё, неожиданно GC становится непригодным, равно как и весь использующий мои классы код.

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

У тебя опять мозг, изнасилованный джавой. Не нужны тебе объекты, разделяемые между потоками. А когда нужны, ты об этом знаешь и также знаешь, что нужно организовывать безопасный доступ к ним, простой заменой Rс на Arc тут не обойдёшься. И только «безопасная» java, которая хочет чтоб программы по сегфолту не падали, но не умеющая следить за многопоточным доступом, пытается решить проблему вот так вот. Но решает она не твою проблему, как программиста, а свою, непадение по сегфолту. Если у тебя, неожиданно для тебя, несколько потоков начали работать с твоим объектом двусвязным списком, то программа твоя скорее всего уже в некорректном состоянии. Но по сегфолту не падает, это да.

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

Пф-ф-ф, уже забыл, как раст создает контейнеры с одним-двумя полями на каждый чих?

Опять месяц городости java-программистов, пошли рассказы про «а у вас ещё хуже».

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

Ещё раз говорю, тупица, не знаешь - не вякай. Читай про перемещение. Собственно в расте есть 3 способа работать с Rc. Можно позаимствовать обычный указатель на данные, счётчик не меняется, данные считаются заимствованными пока жив указатель. Причём указатель может как угодно глубоко лезть во вложенные функции, это уже обычный указатель, они даже не знают, что данными владеет Rc. Второй - перемещение Rc. Счётчик опять же не трогается, компилятор следит за тем чтоб drop у Rc-источника не вызвался. С точки зрения результирующего кода это просто копирование указателя. Третий - клонирование Rc. Делается только явно. Вот тогда счётчик увеличивается. Но только тогда, когда это действительно нужно и программист явно попросил об этом. Простая передача в функцию, присваивание полю, и т.п. этого не сделает.

А изменение счетчика — это не просто одна запись в память, это еще и cache-miss,

Дожили. Фанат GC с его косвенностью для всего, рассказывает что-то про промахи в кэше. Ты реально не представляешь как работают все те волшебные фичи, которые тебе очередной «язык высокого уровня» предоставляет?

Частичная оптимизация передачи ссылок есть даже в питоне, в сраном тормознутом еле ползающем питоне — чем ты собрался хвастаться?

Мне интересно что у тебя вообще в голове за говно? Вот есть проблема. Есть известное решение. И есть место, где это решение реализовано, по твоим же словам «частично». Из этого ты делаешь вывод, что раз питон - говно, то и сам способ решения уже зашкварен и соответственно тот язык, который использует решение правильно тоже зашкварен. Потому что питон пользуется тем же методом, иногда.

А наковыряли то, что «любой ресурс» недопустимо считать любым: память, на которую есть жесткие ссылки

Ну в общем всё понятно, обычный твой уровень философствующего дебила. Для раста твой пример неактуален, ибо лайфтаймы.

Да, вроде как Node можно реализовать на Box или счетчиках ссылок, в том числе copy-on-write (идут в комплекте), но сама реализация дерева крутит указателями и временем жизни вручную.

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

Да пожалуйста, нужно тебе дерево - делай ноды через Rc, а парент - через Weak и всё, проблема решена. Ну или делай нормальный контейнер под требования, возможно с unsafe-оптимизациями. Правда потом какой-нибудь идиот найдёт твой код и напишет «гыгыгы, раст не умеет в деревья».

Именно потому RAII не масштабируем, в отличие от GC.

Чувак, я тебя уже 3 дня носом тыкаю в то где GC не справился и пришлось в С-стайл работать. И даже не где-то в потрохах библиотеки, нет, в пользовательском коде. И у тебя хватает наглости писать что-то о масштабируемости GC?

Пардон, а какой вообще тогда был смысл этой олимпиады с safe/unsafe? Чтобы hello world-ы были красивые, или чтобы не париться о памяти при росте приложения?

Тупица, никто никогда не предлагал unsafe в качестве оболочки всего проекта. Ну, кроме тебя, но ты - местный дурачок и потому не в счёт. Unsafe всегда оборачивает небольшой кусок с магией, сокрытый снаружи вменяемым API. В отличие от волшебного GC, в котором ты не там вызываешь close или допускаешь побег из try-with-resources и получаешь аналог use after free в пользовательском коде. Ты понимаешь разницу между «переписали кусок на raw-pointer’ах чтоб решить задачу» и «заставили пользователей либы пердолиться с небезопасным кодом»?

Охохо, наивность, не слышавшая про фрагментацию памяти.

Очередные сказки джавистов. В твоём GC есть такая штука, называется «поколения». Так что там где в нормальных языках часть хипа пропадает из-за фрагментации, в GC те же самые фрагменты, только что условно называемые живыми.

Кстати, ты в курсе что разработчики либ знают о проблеме фрагментации и применяют меры для снижения её влияния?

Вот поэтому ты искренне считаешь,

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

Argumentum ad Hello Worldum. Мне это до боли

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

Взаимные ссылочки замыканий где?

Т.е. обосравшись ты решил действовать наверняка и свёл задачу к предыдущей, к двусвязному списку? Ну если этот идиотизм реально понадобится, да, можно. Только в виду требований системы владения, придётся так же через Rc/Weak.

Да хотя бы и обычные ссылочки?

Какие ссылочки, болезный? В примере - вектор, владеющий указатель на массив. Можно заменить на Box, будет владеющий указатель на один объект. Можно взять Rc, будет указатель с совместным владением. Можно взять простую структурку, она мувнется внутрь замыкания. Ты же просил пример хранения данных внутри замыкания, а я перечислил вроде бы полный список способов хранить данные в расте, напрямую, через контейнер, через владеющий указатель, через совместно владеющий указатель. Все они возможны для замыкания.

Ну можешь так же захватить невладеющую ссылку, но тогда это будет не хранение внутри замыкания и у замыкания будет лайфтайм.

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

А ты типа веришь, что в волшебных языках это реализовано как-то по-другому что ли? Семантически у всех них аналог захвата Rc, только вместо Rc у них указатель для GC. Ну, или захват всего контекста вызывающей функции ещё можно, не знаю, бывает ли такое в реальности, всё-таки от стека отказываться не хочется.

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

И ты типа веришь, что это даёт тебе индульгенцию? А вот хрена там. Раз ты продолжаешь настаивать на волшебном ВУ, который сам разрешит все проблемы, то изволь отвечать за неудачные попытки. Хотя бы приведя пример «как надо».

Уже давно неактуальные. Крокфорд пришел — порядок навёл.

Ты видимо даже мемчики эти не в состоянии понять. Всё там актуально и будет таким оставаться.

Ага, «не историк». В 60-м почти все языки были ассемблероподобные

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

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

Хотя даже в крестах уже есть move semantic, пусть оно и настолько ублюдочное, что мало кто им пользуется без необходимости.

«Да что ты, черт подери, такое несешь?» (c)

Move semantic, как и куча других фич в C++, была сделана для того, чтобы ей пользовались лишь по необходимости.

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

Ничего из этого не должно использоваться без необходимости.

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

Создай простейший класс, например Point2d.

Если ты из языков с GC языков знаешь только Яву (js сразу куда-то затерялся), то это не моя проблема. В том же Обероне есть записи, можно создать их массив и это будет один кусок памяти. При том язык со сборкой мусора тоже. Кажется, что и в Шарпе так же, хотя не уверен.

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

Во-первых, давай повежливее или иди лесом сразу. Во-вторых, разделяемые между потоками объекты есть в Го, Си, плюсах. Не знаю насчёт Раста.

Вот, скажем, есть у меня дерево классов, хранящих, ну например картинки разные. И управляются они GC. А потом возникает желание добавить класс для изображения в буфере графического API. И всё, неожиданно GC становится непригодным, равно как и весь использующий мои классы код.

Не верю. Объясни поподробнее.

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

И не в последнюю очередь потому я по итогу в PSO отказался от многоверсионности.

что за PSO?

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

это недостатки GC потребовали вывести из под него управление всеми другими ресурсами

Не недостатки, а особенности. С тем же успехом можно сказать, что недостатком стула является то, что на нём неудобно лежать.

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

Я отвечаю на то, что ты пишешь, а не на то, что ты думаешь — libastral у меня устаревшей версии, сорян.

Я тебя научу. Если пишут очевидный бред и постоянно ссылаются на твои утверждения - то это 100% сарказм. Ну или если хочешь, reductio ad absurdum. В этом случае нужно не критиковать предлагаемые решения, тем более так тупо как это сделал ты, а искать, почему вот это предлагаемое решение не является развитием твоих идей.

Не писал я такого. Я писал, что GC так быстро, что не является помехой.

Ты ещё и жалкий врунишка. Ты писал и про Rc как попытку выгадать немного производительности и про избыток производительности CPU. Что ж теперь сдаёшь назад?

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

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

Каким надо быть дебилом, чтоб дать ссылку на опровержение собственных слов? Правильно, дебилом, который не может прочитать и понять даже 1 абзац. Цитирую по твоей же ссылке: «Data synchronization refers to the idea of keeping multiple copies of a dataset in coherence with one another, or to maintain data integrity». Теперь вопрос на четвёрку, какую задачу решают lock-free алгоритмы? Если тебе это сложно, тогда вопрос на тройку, в чём различие применения правильного локфри от простого однопоточного «записываем как получится»?

Я? Зачем он мне нужен?

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

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

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

Короче, ты выдумал несуществующую проблему.

Да, на что я ответил, что абстракции эти чудовищно куцые и не годятся для задач, выходящих за рамки написания браузера

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

Одна из первых ссылок с сайта васяна: https://clojure.org/about/concurrent_programming

Ты неправильно ищешь похвальбы от Васяна. Если искать таким образом, то ты и в расте найдёшь небезопасные блоки и сырые указатели, и легко сделаешь двусвязный список, ничуть не сложнее чем на C. Вот как правильно искать: https://www.clojure.org/about/rationale Это Васян объясняет, зачем мне вообще тратить время на его говноязык. До момента, когда выяснится, что змеиное масло не работает и нужно делать мутексы, ещё несколько месяцев, я пока что наивный читатель и хочу чтоб за меня всё сделалось само. Проматываем вниз и читаем:

  • Immutability makes much of the problem go away
    • Share freely between threads
  • But changing state a reality for simulations and for in-program proxies to the outside world
  • Locking is too hard to get right over and over again
  • Clojure’s software transactional memory and agent systems do the hard part

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

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

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

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

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

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

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

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

Вроде как он все время на свою разработку Python Shared Object ссылается. И вроде как даже ссылка на github с этим PSO выше уже проскакивала.

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

И вот сразу замечательный пример, почему Rust никуда не убежал от этой проблемы:

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

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

Если ты из языков с GC языков знаешь только Яву (js сразу куда-то затерялся), то это не моя проблема. В том же Обероне есть записи, можно создать их массив и это будет один кусок памяти. При том язык со сборкой мусора тоже. Кажется, что и в Шарпе так же, хотя не уверен.

в js так же, «всё есть объект». Оберон никому неинтересен, кроме пары фанатиков. А вот в шарпе да, структуры есть. И много с ними гемора, потому что передача по ссылке и передача по значению сильно различаются, а в коде это не шибко-то очевидно. В основном рекомендуют отказаться от мутабельности структур. Причём, что характерно, это тупо. Именно структуры можно безопасно делать мутабельными. У тебя твоя копия и твори с ней что хочешь. Однако, в рамках «весь отряд идёт не в ногу», в GC языке всё приходится ставить с ног на голову, структуры неизменные, объекты мутабельные.

Во-первых, давай повежливее или иди лесом сразу. Во-вторых, разделяемые между потоками объекты есть в Го, Си, плюсах. Не знаю насчёт Раста.

Я вынужден повторить свой диагноз: мозг изнасилованный джавой. Это не оскорбление, это указание на твою ошибку. Это как когда фанат C уверен, что эквивалентность массива интов и указателя на инт - это что-то вменяемое, потому что он привык к этому бреду. Что до «есть в …» - это то же самое что сказать что в C есть возможность работать с памятью за границей массива. Да, есть, но это не то чем следует заниматься. Если хочешь работать с данными из разных потоков - делай это правильно.

Не верю. Объясни поподробнее.

Ну а как ты реализуешь освобождение ресурсов классом VRamRaster, инкапсулирующий буфер в видеопамяти? Через финализатор или PhantomReference? Утечёт в поколение старых объектов и никогда не освободится. Через AutoClosable? Ну привет, приходится переписывать весь пользовательский код в RAII стиле.

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

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

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

Спасибо, понял. Не говоря о костыльности сразу (это же не лисп, который наш автор почему-то ненавидит), работа явно не завершена, судя по тому, что он пишет на Хабре про отладку и логгирование. И ещё не факт, что она может быть завершена.

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

Тогда иди лесом. Диагност блин нашёлся :)

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

Могу других примеров накидать: раст, например, не позволяет использовать указатель на локальную переменную после выхода из функции. Тоже недостаток, ага.

Так промахнуться немногим дано было.

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

khrundel ★★★★
()

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

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

Мне кажется, вам уже неоднократно говорили, что вы идиот. Но тут тот самый случай, когда это обязательно нужно сказать еще раз.

Вовсе нет. Человек просто уже интуитивно живет в 22-м веке, но для самовыражения использует язык 20-го века.

Он по существу прав. Доказывающие компиляторы физически невозможны из-за комбинаторной сложности доказательства теорем. А «неточное» доказательство — это как раз то, что мы имеем в Rust с его вездесущим unsafe или в C++ с ручным управлением самим оптимизатором. Другой вариант достижения и надежности и высокоуровневости — делать проверки уже в рантайме и платить за это избыточностью. Чудес не бывает.

По поводу «процессоров» он тоже всё правильно говорит. Rust не обеспечивает защиту памяти. Она должна делаться аппаратно, и избыточные кремниевые бюджеты стоило бы пустить на аппаратную поддержку тэгирования, «аппаратные блокировки» и STM, а не на расширение окна OoOE. Работы по таким акселераторам ведутся (в рамках RISC-V), и после детального знакомства с ними смотреть на весь этот горький SMP-катаклизм, с которым нам приходится работать сейчас, без слез уже не получается.

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

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

Всё понятно с этим вашим хрустом. Я даже на своём хипсторском жс могу делать список как человек, а не через анал.

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

А в системах реального времени заранее определяется худший случай и использование динамической памяти не рекомендуется.

Да все понятно, не можешь == не нужно.

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

Я был бы признателен, если бы вы объяснили, как ваш поток сознания соотносится с тем, что цитировал я, а именно:

Кому нужно так жестко заморачиваться, если проблема №1 во всей индустрии сейчас — это «процессоры слишком мощные и нам нечем их загрузить».

Вы, как и идиот это написавший, реально считаете, что главная проблема индустрии – это слишком производительные процессоры?

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

Если у тебя серьезные требования по скорости и список склонен к разрастанию, то как ты собрался этот связный список проходить?

А что ты собрался делать с массивом, который склонен к разростанию и рандомному перестроению? Ой, всё, я опять полез сраться на лор, ну его нахер, пойду чем-нибудь полезным лучше займусь.

crutch_master ★★★★★
()

Ужос страшный. Сами себе проблему создали и сами успешное её побеждают. Охъ лёл

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

Сраного никому не нужного связанного списка

Ой, тоже мне сеньёр, херов. Иди б-дерево сделай на своих массивах обсосанных или какой-нибудь поисковый граф. Костыльщики херовы, сначала сломали себе ноги, а потом пытаются выплясывать.

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

Поэтому RAII - вменяемый способ управления ресурсами, а GC - говно.

У тебя GC работает прямо в ос, умник херов. Это в твоём убогом говнокоде какие-то ресурсы, владение, а в ос постоянная фрагментация памяти, перенос страниц туда-сюда, да и вообще всё, как на любом динамическом недоязычке, лул. Раз GC такое говно, удали ос, пиши с чайника.

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

GC - неработоспособное говно в любом случае.

Вполне работоспособное (мы сейчас про трассирующие сборщики), если оставаться в фундаментальных рамках эффективности этого паттерна:

1. Размер кучи ограничен (например, 1GB) 2. Темп выделения памяти не выше темпа её высвобождения для контроля длительности пауз. 3. Есть способ контролировать базовые параметры GC, типа объема свободной памяти и вовремя реагировать на выход за «зеленую зону».

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

Трассирующие GC вполне себе подходят для задач, в которых долгоживущее состояние хранится или в off-heap, или вообще в СУБД. Что мы и наблюдаем на практике.

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

Скажем так, нам в софте приходится «изящно обходить» то, что разработчики в железе или не захотели, или не смогли реализовать нормально (для нас). Я даже толком не могу надежно сбросить состояние памяти на диск, потому что дисковые контроллеры врут про кэширование. И мне на 1 единицу времени разработки основного алгоритма приходится тратить 10 единиц времени на придумывание аппаратно-зависимых воркэраундов, и 100 единиц времени на сбор статистики того, какое железо как именно врет.

С CPU та же самая проблема. На моем R9 5950X RTT между ядрами в среднем порядка 300 ns. Вместо нормального мессаджинга между ядрами, синхронизация делается через протоколы когерентности кэшей. Спасибо и на том, конечно же, но не такого я жду от железа в третьей декаде 21-го века.

Слава ЖГ, мы уже начинаем переходить к Software/Hardware co-design, когда железо делается специально под требования софта. Это пока не проявляется на массовом сегменте, но движение вперед есть, и хорошее.

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

Интересно кстати пощупать вот это вот на предмет использования чего либо сложнее вектора. А то может пролетарскому софту на расте и не нужны графы эти ваши. А вы копья ломаете. Помнится vertexua объяснял, что нужно писать на расте как на питоне и не морщить извилины. И царь не даст соврать: скриптуха уровня пхп.

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

Помнится vertexua объяснял, что нужно писать на расте как на питоне и не морщить извилины.

Так не получится. На бидоне можно делать всякие списки и прочее.

И царь не даст соврать: скриптуха уровня пхп.

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

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

На бидоне можно делать всякие списки

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

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

PSO — это STM. А эти штуки сложно вытащить из экспериментального статуса. Что не значит, что они не нужны. STM, в частности, хорошо высвечивает проблемы дизайна модели данных языка программирования.

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

Я тебе больше скажу, в Скале при импорте классов-абстракций структур данных по умолчанию импортируются именно их иммутабельные версии, потому что сейчас хороший тон - это скорость выполнения программы, ее масштабируемость и потокобезопасность. А масштабируемость (например, взять Akka с ее сотнями тысяч акторов) и потокобезопасность дают именно иммутабельные данные. Поэтому пишем код в иммутабельном стиле как Одерский завещал. Впрочем это верно много где еще, не только в Скале.

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

Почему я могу выделить массивчик и раскидать по программе ссылку на него, а ссылку на файловый дескриптор не должен, а наоборот, обязан обернуть его в try with resources?

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

Вот, скажем, есть у меня дерево классов, хранящих, ну например картинки разные. И управляются они GC. А потом возникает желание добавить класс для изображения в буфере графического API. И всё, неожиданно GC становится непригодным, равно как и весь использующий мои классы код

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

Не нужны тебе объекты, разделяемые между потоками

Я скозал!

Проблему разделяемых между потоками объектов решает Clojure.

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

Ещё раз говорю, тупица, не знаешь - не вякай. Читай про перемещение. Собственно в расте есть 3 способа работать с Rc

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

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

На что я здесь должен отвечать? Ты высрал линии из говна и ноль аргументов мне в ответ, и меня уже это напрягает.

Да пожалуйста, нужно тебе дерево - делай ноды через Rc, а парент - через Weak и всё, проблема решена. Ну или делай нормальный контейнер под требования, возможно с unsafe-оптимизациями. Правда потом какой-нибудь идиот найдёт твой код и напишет «гыгыгы, раст не умеет в деревья»

Не ответил на мой аргумент с циклической ссылкой на дерево из значения дерева.

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

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

Кстати, ты в курсе что разработчики либ знают о проблеме фрагментации и применяют меры для снижения её влияния?

Они могут знать сколько угодно — только решить они ее не могут. Я уже выше детально описал суть проблемы менеджеров памяти на фиксированных ссылках.

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

А я тебе ответил, почему на сложных примерах твое «решение» не будет работать. Привел бы сложный пример — сразу бы поржали всем лором над удобством раста.

Т.е. обосравшись ты решил действовать наверняка и свёл задачу к предыдущей, к двусвязному списку? Ну если этот идиотизм реально понадобится, да, можно. Только в виду требований системы владения, придётся так же через Rc/Weak

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

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

Ссылки замыканий на замыкания. Суть функциональных языков заключается в том, что все данные хранятся в замыканиях — это альтернатива объектам, то есть, хранению функций в данных. И такой подход требует гибкого и простого инструмента организации этих ссылок, иначе у тебя будет «ехал Box через Rc, видит Rc Cell в Mutex...» — и всё это для какой-то копеечной базовой функциональности, это еще ничего сложного не начали писать.

А ты типа веришь, что в волшебных языках это реализовано как-то по-другому что ли? Семантически у всех них аналог захвата Rc, только вместо Rc у них указатель для GC

Вопрос не в том, что там под капотом, вопрос в том, как на это можно писать работающий код. И на Rust-е это делать сильно сложнее.

И ты типа веришь, что это даёт тебе индульгенцию? А вот хрена там. Раз ты продолжаешь настаивать на волшебном ВУ, который сам разрешит все проблемы, то изволь отвечать за неудачные попытки. Хотя бы приведя пример «как надо»

Ответил уже: Си, DSL.

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

Move semantic, как и куча других фич в C++, была сделана для того, чтобы ей пользовались лишь по необходимости

А в остальные дни сидели на копьях из неявного копирования? Что характерно, проблема была осознана еще раньше, когда начали делать copy elision для тех же возвращаемых значений — некоторые типы просто не умеют копироваться, их по-другому можно передать только через костыли с промежуточными ссылками.

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

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

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

Я тебя научу. Если пишут очевидный бред и постоянно ссылаются на твои утверждения - то это 100% сарказм

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

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

Уже отвечал — это проблемы одной конкретной Java, которые не имеют отношения к проблемам GC. Сделай на Rust всё приложение на одних только связанных списках, в том числе строки и массивы — и ты получишь похожую проблему, даже безо всяких GC.

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

А то, что пока у тебя 90% разнообразия функций крутятся в одном потоке, то рано или поздно ты не угадаешь с их ресурсоемкостью и они завалят тебе поток. Как это обычно и случается в GUI с такой архитектурой. А устранение зависания от каждой такой функции — это целая отдельная эпопея с водружением костылей, потому для 100% этого сразу сделать нельзя. Если же ты попытаешься исходить из предположения «100% функций должны быть изначально масштабируемыми», то придешь примерно к тем же выводам, к которым пришел я.

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

Дай бог, дай бог. У мозиллы не получилось — одна лишь надежда на гугл.

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

Не нужны. Мутексы — изначально ненадежный инструмент, высокоуровневый код не может на них опираться.

Что, если не транзакционная память, кажется тебе той самой серебряной пулей

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

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

работа явно не завершена, судя по тому, что он пишет на Хабре про отладку и логгирование. И ещё не факт, что она может быть завершена

Работа явно не завершена, но отладочка там — это моя гордость. Когда сишный lock-free код за ручку тебя приводит к своим багам — такое мало кто умеет. Обычно происходит наоборот: «баг видишь? А он есть».

По поводу логирования: на моем текущем проекте, где я работаю за нефть, проблема логирования точно так же не решена. И я тупо не знаю проекта, где была бы решена, кроме, наверное, неплохого решения в Varnish-е, где ты можешь в рантайме менять детализацию логов — не знаю только, почему мало кто перенял эту модель. Подозреваю, что потому что следующей проблемой такого логирования является то, что просто нет готовых инструментов для хранения/обработки/анализа логов, поскольку всякие там кибаны-логстэши-эластики и прочий бесполезный мусор не умеет эффективно анализировать логи в нагруженных многопоточных/распределенных системах.

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

Могу других примеров накидать: раст, например, не позволяет использовать указатель на локальную переменную после выхода из функции. Тоже недостаток, ага

Забыл упомянуть, зачем нужно было изначально использовать указатель.

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

1. Размер кучи ограничен (например, 1GB) 2. Темп выделения памяти не выше темпа её высвобождения для контроля длительности пауз. 3. Есть способ контролировать базовые параметры GC, типа объема свободной памяти и вовремя реагировать на выход за «зеленую зону»

Основные проблемы в средах выполнения с GC возникают из-за убогости базовых структур данных. Go может крутить сотни гигабайт без особых сложностей. Но мой любимый пример — это JS, который несмотря на динамическую типизацию и горы наследия, на которое нужно постоянно оглядываться, позволяет достичь производительности жавы — потому что ассоциативные и простые массивы в качестве базовых структур данных позволяют делать чудеса. Вот Go — это в каком-то смысле тот самый JS с массивами, но без динамической типизации, и он активно наступает на пятки C/C++ по производительности, по крайней мере на тех задачах, под которые адаптирован.

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

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

Кстати, это эпичный трешак. На лине уже вторые-третьи поколения ФС для флеш-памяти, а под винду до сих пор ничего подобного нету. По итогу утюги умеют в защищенный режим с оптимизированным некэшированным доступом к флешу, а десктопный комп — нет. «Прогресс», чо. Рыночек, ага. Просто очередной пруф того, что дай рыночку волю — он будет дальше торговать гафниево-палладиевыми перфокартами, изготовленными по технологии 3 нанометра.

Слава ЖГ

Кто такой ЖГ?

byko3y ★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)