LINUX.ORG.RU

Этот ваш reference counting

 ,


1

4

Во время попытки доказать одному товарищу, что Swift — ненужно, я наткнулся на интересную особенность:

import Foundation

let noLeak = 131028
let withLeak  = noLeak*10

class R {
    var _a : R?
    init(a : R?) {
        _a = a
    }
}

func test(n:Int, leak:Bool) {
    var p0 = R(a : nil)
    var p = R(a : p0)
    for _ in 1...n {
        p = R(a : p)
    }
    if leak {
        p0._a = p
    }
}

test(withLeak, true)
println("Evil leaking function")
test(noLeak, false)
println("Good function")

Первый вызов test просто течёт в лучших традициях Reference Counting, а вот второй падает со stack overflow (деаллокация, похоже, делается рекуррентно).

Интересно, есть ли такое же в Rust?


Ответ на: комментарий от quantum-troll

В релизе тоже падает, можешь в этом сам убедиться.

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

Потом, если бы автор что-то понимал в происходящем, он бы не писал эту его функцию len() вообще.

Лол, функция len() была скопирована из учебника по rust вместе с остальным кодом List.

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

Для непонятливых объясняю.

Не хотел бы вмешиваться, но тот код на крестах, куда вы влезли, был просто переписанный код Rust. В теме спросили, будет ли в C++ такое же поведение.

Какое поведение будет в C++ при использовании смарт-указателей было весьма очевидно, но человек всё равно написал код, причем написал там рекурсивную функцию, которая вызывается до деструкторов, а когда я ему на это указал, то сказал, что проблема не в этом. То есть он только всё запутал - из одной проблемы сделал две. Пришлось поправить его код, чтобы проблема стала совсем очевидна.

Ваш же деструктор, объективно, плохо написан. Вы же не пишите на C++ на работе?

Я пишу на C++ на работе и мне за это платят деньги. Мой деструктор делает то же самое, что происходит при рекурсивном вызове деструкторов по умолчанию через автоматические указатели, только делает он это не через стек, а через кучу посредством std::list, поэтому переполнения стека не происходит. Это решение «в лоб» с минимальными изменения, и лучше ты не сделал. Чтобы сделать лучше нужно не ограничиваться деструктором, но «контейнер» этот изменять нет смысла, потому что такой контейнер уже и так есть в С++11 - std::forward_list - и в чем была идея данного велосипеда кроме как показать как выстрелить себе в ногу - совершенно не понятно. Человек специально выстрелил себе в ногу, а виноват я, что не научил его стрелять красиво.

asaw ★★★★★ ()
Ответ на: комментарий от quantum-troll

Запущен на playground в режиме Release. Если ты знаешь, как написать подходящий drop - покажи. У меня не получилось.

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

Лол, функция len() была скопирована из учебника по rust вместе с остальным кодом List.

Это учебный код, для демонстрации.

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

Я пишу на C++ на работе и мне за это платят деньги.

Какое досадное упущение, однако.

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

Чья бы корова мычала. Эксперты тоже мне.

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

Чья бы корова мычала. Эксперты тоже мне.

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

Очевидно, ты не умеешь программировать. Пожалуйста, не делай этого больше.

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

Эти эксперты хотя бы не отрицают существования копирующего мусорщика.

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

Единственный твой аргумент - бездоказательные обзывательства и ярлыки. Всё, больше ничего. Ноль. Пустышка. Бестолковая школота. Идешь в игнор.

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

Я тоже не отрицаю в теории, но что они ещё остались в реальной жизни и на них продолжают молиться фанатики всех мастей - это, конечно, недосмотр.

asaw ★★★★★ ()
Ответ на: комментарий от quantum-troll

Всем нам было бы интересно увидеть правильную версию.

fmdw ()

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

anonymous ()

Любой инструмент можно использовать неправильно. Ты доказал лишь, что и Swift тоже можно. В реальных же задачах вопрос ставится таким образом: «Можно ли использую конкретный инструмент правильно решить задачу за определенное время и вместится в бюджет».

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

Любой инструмент можно использовать неправильно. Ты доказал лишь, что и Swift тоже можно.

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

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

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

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

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

Apple это самая богатая IT-компания в мире. Причём она тратит на разработку больше всех денег. Ты реально думаешь, что они не осилили или не осилили нанять тех, кто осилит?

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

Ты реально думаешь, что они не осилили

Где я такое писал?

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

Причём она тратит на разработку больше всех денег.

Просто из любопытства: разработку чего? Именно программного обеспечения? Пруф будет?

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

Если хороший, компактифицирующий generational сборщик - он на порядок быстрее подсчета ссылок работает (и даже быстрее ручного управления памятью, если не писать собственные аллокаторы).

Безотносительно вопроса о ГЦ - какой смысл говорить о скорости подсчёта ссылок против ручного управления памятью? Ведь подсчёт нужен именно там, где вручную особо не поуправляешь.

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

Лично я больше работаю с языками без ГЦ и вполне устраивает.

Как бы ты решил данную задачу на Swift и/или Rust?

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

Как бы ты решил данную задачу на Swift и/или Rust?

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

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

На Rust уже был код=)

Берем связный список на Rust(вроде как из документации брали) и создаем большое число объектов. Падаем при попытке разрушить список. В C++ если сделать на unique_ptr так же падаем. Вот и приходится удалять итеративно в цикле.

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

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

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

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

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

Можно в деструкторе взять next в переменную, а в инстансе его обнулить. И так в цикле.

var t = self;
while (t) {
    var n = t.next;
    t.next = nil;
    t = n;
}

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

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

Ага, спасибо (весь тред не читал, да).

Ну тогда я не вижу проблемы удалить в цикле, ну нет TCO.

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

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

Ты прав, так работает.

class R {
    var _a : R?
    init(a : R?) {
        _a = a
    }
    
    deinit {
        var i = self._a;
        while let i2 = i {
            var t = i2._a
            i2._a = nil
            i = t
        }
    }
}

(Да это же сишный код!)

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

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

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

сишный код

В общем-то для seasoned объективщиков свифт не более, чем реинкарнация объектива с менее wordy синтаксисом, а сам объектив — не более, чем надстройка над сишкой, довольно тривиальная и легко схватываемая на лету в духе сишки. В отличие от растов и уж тем паче крестов.

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

Не знаю, чо я сразу не допер, тупил вчера весь день.
<...>
К сожалению, мысль теперь похоронена под флудом этого гц-хейтера.

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

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

Моих комментов тут раз, два и обчелся, не хватало еще в таких срачах участвовать. Спи иди детектор хренов.

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

Даже в сообществе Rust, которое, вроде как более «системное», это вызывало трудности...

Потому что раст пытается дать дополнительные гарантии. В итоге, некоторые «тривиальные» вещи пишутся наоборот «сложнее».

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

ARC намного проще Rust-а для программиста.
В Rust все эти расходы во время выполнения программы нулевые за счёт усложнения языка и жизни программиста.

В расте есть и RC и ARC и аналог плюсовых unique_ptr.

Вообще какой-то странный спор про производительность. В языках без ГЦ принято, по возможности, использовать стек. Я хз как там в свифте, но сильно удивлюсь, если там нет чего-то типа unique_ptr.

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

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

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

Если когда-нибудь сделают TCO - не нужно будет.

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

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

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

Ну и почему ты думаешь, что это идеоматический код?

Потому что он часто приводится в пример - Box, автоматическая чистка через RAII.

В стандартной библиотеке списки реализованы совсем иначе.

В стандартной библиотеке разве есть односвязный список?

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

Потому что он часто приводится в пример - Box, автоматическая чистка через RAII.

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

В стандартной библиотеке разве есть односвязный список?

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

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

причем написал там рекурсивную функцию, которая вызывается до деструкторов

Так же было в оригинальном примере на Rust.

Я пишу на C++ на работе и мне за это платят деньги.

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

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

Я бы на твоём месте поприкрутил снобизм и умерил ЧСВ. От тебя кроме болтовни в этой теме вообще ничего нет. Вот это:

    ~ListNode()
    {
	while(next && next->next) 
	    const_cast<List*>(&next)->reset(const_cast<List*>(&(next->next))->release());
    }
- тоже мой код. И он ничем не лучше - это я тебе как автор заявляю. Потому что дело вообще не в этом коде. А разбирать ты что-то будешь тогда, когда сам чего-нибудь осмысленное напишешь.

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