LINUX.ORG.RU

языки без сборки мусора

 


2

7

Всем привет!

А какие есть годные языки без сборки мусора? Ну, т.е. кроме С, С++ и Rust.

Так, чтобы не просто опциональное ручное управление, а чтобы весь язык и стандартная либа были ориентированы на работу без gc

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


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

программы на которых выполняются не медленнее и занимают не больше места, чем написанные с идентичным алгоритмом на C++ и скомпилированные GCC

Регулярно в бенчмарках такое видно. Причём насасывают кресты от языков с GC.

no-such-file ★★★★★
()
Ответ на: комментарий от WitcherGeralt

Если тебе что-то в жёстком реалтайме нужно делать, то это очевидное требование

Не совсем очевидное. Чем GC в D мешает реалтайму?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Он работает константное время? По-моему писать на D нечто реалтаймовое мешает в первую очередь то, что никто не пишет на D даже не реалтаймовое.

WitcherGeralt ★★
()

А какие есть годные языки без сборки мусора?

Никаких нет.

Ну, т.е. кроме С, С++ и Rust.

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

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

Регулярно в бенчмарках такое видно.

Можно пример?

Причём насасывают кресты от языков с GC.

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

Поэтому всё-таки интересен пример.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

Не, там программа-бинарник меняет поведение при изменении исходного кода на ходу.

https://vlang.io/img/hot.webm

Видел такое в Common Lisp, Smalltalk и Erlang. Но маленькие бинарники никто из них делать не умеет.

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

интересен пример

Далеко ходить не надо https://github.com/kostya/benchmarks или https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=f...

а не идентичные алгоритмы

А что такое идентичные алгоритмы тогда? Которые компилируются в одинаковый машкод?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

А что такое идентичные алгоритмы тогда? Которые компилируются в одинаковый машкод?

Которые одинаковы с точки зрения описания последовательности действий.

Например, сравниваем Kotlin и C++. В версии на C++ элементы в массив добавляются по одному, в версии на Kotlin заполняются с удвоением длины массива. То есть в версии для C++ вместо tape.push_back(0) должно быть tape.resize(tape.size()*2, 0);

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

Например, сравниваем

Ты не сравнивай, а пили патч.

tape.push_back(0)

В крестах же вектор из коробки реализует удвоение длинны.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

Там в плюсах дэбильное чтение из файла плюс fflush... А вектор и так увеличивается, но там есть переменная для задания значения на сколько он будет увеличиваться вроде.

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

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

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

Там в плюсах дэбильное чтение из файла плюс fflush

fflush там во всех версиях. А что не так с чтением файла? Файл в строку можно прочитать лучше?

А вектор и так увеличивается

Это понятно, но при перемещении с 0 на 256 на Kotlin будет 8 итераций в каждой из которых один раз сравнится pos с size и размер массива удвоится. А на C++ будет 256 итераций, в каждой pos будет сравниваться с size в начале цикла, потом ещё раз сравниваться внутри push_back.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

В крестах же вектор из коробки реализует удвоение длинны.

Тогда в Котлин надо внутри цикла записывать одно значение в конец массива, а удваивать только если текущий конец массива дошёл до зарезервированного объёма.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

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

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

free дерева произвольного размера.

free от любого одного элемента выполняется константное (приблизительно время). А free от дерева зависит от того, как напишешь. Можно дерево размещать в непрерывном pool'e, тогда будет один free, можно на каждый элемент выделять отдельно память, тогда пропорционально количеству элементов. А вот в случае GC даже не пропорционально количеству элементов, вот в чём беда.

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

Можно дерево размещать в непрерывном pool'e

Что мешает при GC так делать?

А вот в случае GC даже не пропорционально количеству элементов

Ну да GC же за пивом ещё бегает и из вредности noop гоняет.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

А толку

Да это я так, в порядке глумления. Ты просил примеры, я их дал. Там ведь не только brainfuck. И ведь это игрушечные бенчи. А на практике в web framework contest в реалистичных тестах single query/mutli query кресты вообще ничем не выделяются, некоторые варианты сосут даже у руби.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Ну да GC же за пивом ещё бегает и из вредности noop гоняет.

Скорость GC зависит от количества несобранных объектов.

$ cat test-gc.lisp
(time (gc :full t))
(defvar *a* (list 1))
(setf *a* nil) ; удалили один элемент
(time (gc :full t))
(setf *a* (make-list (* 16 1024 1024)))
(setf *a* (cdr *a*)) ; снова удалили один элемент
(time (gc :full t))

$ sbcl --script test-gc.lisp
Evaluation took:
  0.005 seconds of real time
  0.004613 seconds of total run time (0.004613 user, 0.000000 system)
  [ Run times consist of 0.005 seconds GC time, and 0.000 seconds non-GC time. ]
  100.00% CPU
  8,281,356 processor cycles
  0 bytes consed

Evaluation took:
  0.004 seconds of real time
  0.004652 seconds of total run time (0.004652 user, 0.000000 system)
  [ Run times consist of 0.005 seconds GC time, and 0.000 seconds non-GC time. ]
  125.00% CPU
  8,351,616 processor cycles
  0 bytes consed

Evaluation took:
  1.626 seconds of real time
  1.625791 seconds of total run time (1.490162 user, 0.135629 system)
  [ Run times consist of 1.625 seconds GC time, and 0.001 seconds non-GC time. ]
  100.00% CPU
  2,919,939,416 processor cycles
  0 bytes consed

В первом случае удаление элемента произошло за 0.004 секунды, а во втором — за 1.626 секунды. Разница — 6 порядков.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

В реалтайме произвольную херню не вытворяют, не релевантно. Ты можешь замерить время некоего набора операций и вычислить время на которое можно расчитывать. Даже на линуксе при прочих равных время выполнения будет предсказуемым, тем более с preempt_rt. А уж в настоящей RTOS и подавно. С GC у тебя вообще ничерта не предсказуемо.

Впрочем, как я уже сказал выше, в Go, судя по тому, что я слышал в одном докладе, GC должен работать в более-равные промежутки дожен отрабатывать за константное время (точнее не дольше заданного). Хз, не вникал. Мб где-то ещё такое есть.

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

А ещё можно получить такое:

* (defvar *a* (make-list (* 32 1024 1024)))
*A*
* (gc :full t)
Heap exhausted during garbage collection: 0 bytes available, 16 requested.
Gen  Boxed Unboxed   LgBox LgUnbox  Pin       Alloc     Waste        Trig      WP GCs Mem-age
 0       0       0       0       0    0           0         0    10737418       0   0  0,0000
 1       0       0       0       0    0           0         0    10737418       
...
Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb>

Для программы памяти хватает, а для сборщика мусора — нет.

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

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

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

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

Я понимаю, если это сервис, обрабатывающий прилетающие данные, там рано или поздно будет время продохнуть, но что делать, если нагрузка постояная? GC основываясь на статистике будет работу планировать? Или просто течь?

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

GC основываясь на статистике будет работу планировать?

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

monk ★★★★★
()
Ответ на: комментарий от no-such-file

на практике в web framework contest в реалистичных тестах single query/mutli query кресты вообще ничем не выделяются

Кто-то рассчитывал, что кресты будут ждать БД быстрее?

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

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

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

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

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

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

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

Он — школотрон-недоучка с кармановщиной головного мозга и СДВГ, не обращай внимания.

Если тебе что-то в жёстком реалтайме нужно делать, то это очевидное требование.

Вот проблема состоит в том, что ТС даже примерно свою предметную область не обозначил. И спрашивает не ЯП для жёсткого реалтайма (== адекватная постановка вопроса), а ЯП без сборки мусора (== сектантство).

rebforce
()
Последнее исправление: rebforce (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Но я про него вообще ничего не знаю, а от вопросов про его GC ты ушел.

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

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

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

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

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

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

Кстати, про джаву в рилтайме - давно, года три-четыре назад, на одном буржуйском форуме обсуждался этот момент и сторонники сборщика мусора привели в доказательство что Тейлз Рейтеон(*) разработали то ли систему управления баллистическими ракетами, то ли систему ПРО от баллистических ракет. Эта система написана на джаве. И там еще какой рилтайм. Так вот сдается мне, что они там просто выделяют этак 256 гигов памяти на старте и потом просто не парятся.

* - одно из ведущих предприятий ВПК на Западе

anonymous
()

Тебе зачем? Если че, тормозит не GC, а интерпретация байткодов и JIT, это все часто в ЯП идёт вместе.

Обычно нативный код с GC норм. Вон в Go/D разница с C/C++/Rust небольшая. В OCaml/Haskell тоже если не косячить со списками

А все что начинается с байткода будет заставлять машину стонать и пердеть пока/если не соберётся JIT в натив. Ну и если машина от перегрева не сгорит до этого.

Примеры - JVM/.NET/Racket/Android Dalvik. Например в Android сейчас уже натив собирается при установке

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

одно из ведущих предприятий ВПК на Западе

легко нагуглил гражданскую контору

https://www.aicas.com/cms/en/JamaicaVM

но это же немцы - у них всё с какими-то отклонениями

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

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

Например, есть шара, из неё нужно раз в 50мс взять картинку (условная обработка видео — 20fps), следовательно, за эти же 50мс ты должен успеть её обработать. Для упрощения допустим, что память выделяется одинаково, выделенная за цикл память освобождается 5мс, а GC бесплатный. Без GC, освобождая память на ходу, ты укладываешься в 47мс, а с GC в 42. Замечательно, там и там пока Ок. Но если в первом случае обработка в цикле стабильно будет занимать ±одно и то же время, то во втором рано или поздно придёт GC и ты породолбаешь кадр.

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

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

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

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