LINUX.ORG.RU

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

И вот вам ещё, серьёзные парни, моя клоунская развлекуха:

http://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=ghc&lang2=gcc

Обычный Си уделывает Хаскель по производительности, потому что компилятор gcc тоже прекрасно понимает, что такое чистота, и умеет сокращать чистые вычисления. Таким образом, введённые в Хаскель концепции не привели к росту производительности.

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

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

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

Это не говоря, о монаде State.

Короче, учите мат.часть

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

Хотя, насколько я понял, монада - это по сути переопределяемая «точка с запятой» из Си. Смысл монады в том, что она позволяют абстрагировать процесс порождения побочных эффектов и взять его под контроль. За счёт этого якобы можно реализовать внутри языка транзакции, call/cc, undo и т.п..

Насколько это в реальности возможно и насколько технологически сложно - я пока не выяснил.

Например, я спросил (тему не буду искать), легко ли сделать с помощью монад имитацию языка с исключениями (throw/catch), и оказалось, что на Хаскеле это можно, но нетривиально.

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

Ребята, вы сделали мой день, спасибо! Единственные полезные комментарии за 6 страниц треда!

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

В С++, если функция не вызвана из main прямо или косвенно, то она не будет исполнена. То же самое, без монад и теорката.

обработчик прерывания, сигналов

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

Обычный Си уделывает Хаскель по производительности, потому что компилятор gcc тоже прекрасно понимает, что такое чистота

Зато не понимает что такое ленивость, и тупо будет считать массив из 100 миллионов элементов, хотя нужны только первые 10 т.е. нельзя иметь функций типа (take 10 (range 1..))

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

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

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

Обычный Си уделывает Хаскель по производительности, потому что компилятор gcc тоже прекрасно понимает, что такое чистота

Только сейчас прочитал. Чушь какая-то. Все зависит от задачи, от ситуации. Может быть, и наоборот. К примеру, у меня код на haskell часто быстрее аналогичного кода на rust в сложных задачах.

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

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

Пользуясь случаем, хотел спросить. Вот есть у меня цепочка проверок Check1...CheckN :: a -> Either Error a и монадическая цепочка x >>= Check1 >>= Check2 ... >>= CheckN. Превратится ли это там где-то глубоко под капотом в что-то такое?

If !Check1(x) then Error="Check1 failed"; goto @End
If !Check2(x) then Error="Check2 failed"; goto @End
...
If !CheckN(x) then Error="CheckN failed"; goto @End

End: ...
Ну и то же самое про монаду стейт. Превратится ли это во что-то си-подобное, с присваиванием <- get и put?

Просто вопрос в том, на низком уровне, в готовом виде, оно там всё оптимальное или не очень?

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

Если компилировать с опцией "-O2", то на счет State скорее, что да, будет соптимизировано. На счет Either точно не знаю.

Здесь важно, есть ли у функций прагмы INLINE или INLINABLE. В рамках одного модуля компилятор GHC обычно сам достаточно хорошо инлайнит, но если функция вызывается из другого модуля, то бывает иногда, что ему нужно помочь.

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

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

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

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

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

А так в общем иногда бывает, что и NOINLINE помогает, когда мы точно указываем, что инлайнить, а что - нет

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

Спасибо за подробный ответ. Мне нравится писать некоторые свои пет-прожекты на хаскеле, сейчас вот вникаю в extensible effects. Вообще язык богат на интересные идеи. И всё нравится, кроме аспекта производительности: нужно во многом разобраться, чтобы писать эффективный код. Тот же seq в нужные места ставить, понимать, что имеет смысл попробовать заинлайнить, boxed-unboxed и т.д.

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

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

Да, с boxed-unboxed тоже надо аккуратно. И на эту тему есть прагмы. Вообще, если посмотреть на код в стандартных библиотеках, то он обычно весь напичкан прагмами.

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

Еще есть rewriting rules, когда можно самому задать, как сокращать код в некоторых конкретных случаях. Тоже через прагмы.

По себе могу сказать, что писать на haskell эффективный код вполне можно, но писать такой код на любом языке непросто, даже на java и си++. Везде есть нюансы

dave ★★★★★
()
Последнее исправление: dave (всего исправлений: 1)

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

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

Это был не он.

Но вообще-то есть тот же hblas и другие биндинги ко всяким таким библотекам.

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

Типа что про производительность это наброс, думал ты про это. Ещё ден73 скрыл анонимов вроде как.

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

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

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

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

У каждого языка свое предназначение. Производительность проседается на вполне конкретных вещах, типа GC или GIL.

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