Re[12]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 29.09.04 11:48
Оценка:
Здравствуйте, WolfHound, Вы писали:

G>>У тебя на компе будет ~14.16 секунд. Против 8.66 твоих. Теперь ты примерно в 1.6 раз быстрее.

WH>У меня Execution: 13.85 Garbage collection: 0.00 Total: 13.85
G>>А разница в расходе памяти объясняется только отсутствием упаковки bool массивов.
WH>Я тебе больше скажу... Этим же объясняется и разрыв в производительности... См ниже...
G>>Ну как, сделаешь версию на char?
WH>Сделал... Блин я чуть со стула не упал... 13.5022

WH>Но оказывается узкое место ПАМЯТЬ...

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

Неплохой компилятор у Clean. Но зело глючный — писать на нем серьезные программы страшновато. У меня он на довольно простых вещах крешится.
Re[11]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 29.09.04 13:47
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

Нет, дело не в этом. Дело именно в наличии/отсутствии операций с модифицирующей семантикой, как ты и написал вначале. А для цикла несложно ввести нормальную функциональную семантику. Пример.

Цикл foreach приводится к такой общей форме: foreach X in C do Something( X, S ), где С — коллекция, Х — элемент, а Something изменяет состояние объекта S (побочное действие), не возвращая ничего.

1) Изменяем Something таким образом, что она возвращает новое состояние S, не меняя исходное. Snew = Something( X, S )
2) Таким образом, цикл for — это функция, преобразующая исходное состояние S в состояние Snew посредством применения серии операций Something. Что соответствует рекурсивному паттерну (Erlang):

foreach( [ X | C ], S, Something ) -> foreach( C, Something( X, S ), Something );
foreach( [], S, _ ) -> S


Собственно, все. Как видишь, здесь тоже вполне можно фиксировать квантовые шаги, в которых S (в нашем случае — ltList) неполон. И ничего. Выполняться будет совершенно идентично циклу.

S>Примеры функционально плоховыразимых задач лежат не здесь. Пока состояние маленькое, можно пользоваться семантикой копирования. В конце концов, есть алгоритмы SSA и SSI, которые превращают любую императивную программу в функциональную.

Прикольно. Ссылки приведешь?
Re[12]: ФП: вводная статья
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.09.04 14:26
Оценка:
Здравствуйте, Gaperton, Вы писали:

S>>Примеры функционально плоховыразимых задач лежат не здесь. Пока состояние маленькое, можно пользоваться семантикой копирования. В конце концов, есть алгоритмы SSA и SSI, которые превращают любую императивную программу в функциональную.

G>Прикольно. Ссылки приведешь?
Э-э... пока что сам разбираюсь. Услышал ссылку на них, пока гуглю. Ключевые слова — single state assignment и single state information.
Фактически, это формализация того, что ты только что произвел "на пальцах".
P.S мне самому это требуется для преобразования кода на императивном языке (MSIL) в функциональную форму. А это, в свою очередь, надо для того, чтобы реализовать оптимизацию полиморфных запросов. На основе функционального представления будет сформирован предикат, среди термов которого придется искать допускающие индексный поиск. После оценки стоимости выполнения каждого из вариантов, надо будет сгенерировать императивный код, выполняющий index seek по выбранным термам, и вычисление остальных для каждого результатв
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: ФП: вводная статья
От: Quintanar Россия  
Дата: 29.09.04 15:48
Оценка:
Здравствуйте, Gaperton, Вы писали:

WH>>Но оказывается узкое место ПАМЯТЬ...

G>Так я и предполагал, но говорить не стал — вдруг ошибусь? Ее все-таки в восемь раз активнее читать приходится, это не могло не повлиять на производительность. Но того, что это единственный значимый фактор, я, конечно, не ожидал. Прикольно.

G>Неплохой компилятор у Clean. Но зело глючный — писать на нем серьезные программы страшновато. У меня он на довольно простых вещах крешится.


На Haskell'e массивы помедленнее работают Моя программа выполнилась за 66 секунд, программа на С++ за 24. Причем пришлось попинать ghc, чтобы он улучшил скорость программы. Одна оптимизация с INLINE сократила время выполнения на 24 секунды. Так что ghc оптимизировать еще и оптимизировать. Вариант с битовыми массивами работал еще медленнее, хотя я его не оптимизировал.

import Data.Word
import Data.Array.MArray
import Data.Array.IO

type Atype = IOUArray Word32 Word8

newIOArray::(Word32, Word32) -> Word8 -> IO Atype
newIOArray = newArray

size::Word32
size = 100000000

{-# INLINE delete_elems #-}

delete_elems::Atype->Word32->Word32->IO Atype
delete_elems array i fi
    | i >= size = return array
    | otherwise =
        do
          writeArray array i 1
          delete_elems array (i+fi) fi

{-# INLINE sieve #-}

sieve::Atype->Word32->IO Atype
sieve array i
    | i == size = return array
    | otherwise =
        do
          elem <- readArray array i
          array <- if (elem == 0) then delete_elems array (i*2) i else return array
          sieve array (i+1)

main = 
    do
      array <- newIOArray (1,size) 0
      array <- sieve array 2
      return ()
Re[14]: ФП: вводная статья
От: Gaperton http://gaperton.livejournal.com
Дата: 29.09.04 16:46
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q> Здравствуйте, Gaperton, Вы писали:


WH>>>Но оказывается узкое место ПАМЯТЬ...

G>>Так я и предполагал, но говорить не стал — вдруг ошибусь? Ее все-таки в восемь раз активнее читать приходится, это не могло не повлиять на производительность. Но того, что это единственный значимый фактор, я, конечно, не ожидал. Прикольно.

G>>Неплохой компилятор у Clean. Но зело глючный — писать на нем серьезные программы страшновато. У меня он на довольно простых вещах крешится.


Q>На Haskell'e массивы помедленнее работают Моя программа выполнилась за 66 секунд, программа на С++ за 24. Причем пришлось попинать ghc, чтобы он улучшил скорость программы. Одна оптимизация с INLINE сократила время выполнения на 24 секунды. Так что ghc оптимизировать еще и оптимизировать. Вариант с битовыми массивами работал еще медленнее, хотя я его не оптимизировал.


1) Попробуй пометить аргументы функций как strict. Насколько я помню, это делается так же как в Clean (!). Strictness analyzer не способен определить все strict вызовы, ему надо помочь.
2) Попробуй использовать STUArray c типом Bool(Data.Array.ST).

Может, будет лучше. А может, и нет.
Re[15]: ФП: вводная статья
От: Quintanar Россия  
Дата: 29.09.04 17:45
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>1) Попробуй пометить аргументы функций как strict. Насколько я помню, это делается так же как в Clean (!). Strictness analyzer не способен определить все strict вызовы, ему надо помочь.

G>2) Попробуй использовать STUArray c типом Bool(Data.Array.ST).


strict аргументов там нет, да и так там ничего ленивого в сущности нет. STUArray работает буквально на пару секунд побыстрее. С Bool оба массива тормозят — 1м30 и 1м28 соответственно.
Re[12]: ФП: вводная статья
От: prVovik Россия  
Дата: 29.09.04 19:46
Оценка:
Здравствуйте, WolfHound, Вы писали:

Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[13]: ФП: вводная статья
От: WolfHound  
Дата: 29.09.04 19:52
Оценка: +1
Здравствуйте, prVovik, Вы писали:

V>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.

Ну выступи. Ибо ICC у меня нет. К томуже на таких расчетах VC++ тоже рулит.
... << RSDN@Home 1.1.4 rev. 185 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[13]: ФП: вводная статья
От: FR  
Дата: 29.09.04 20:09
Оценка:
Здравствуйте, prVovik, Вы писали:

V>Здравствуйте, WolfHound, Вы писали:


V>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.


задача уперлась в память так что ни какой ICC не поможет.

Да всем, вам не кажется что ваши результаты имеют очень малое отношение к реальной скорости кода созданного разными компиляторами и только показывают что они способны создавать программы которые успевают просчитать элемент массива быстрее чем идет обращение к памяти(не лезущей в кеш), для получения реальных результатов быстродействия надо мерять на малых массивах.
Re[14]: ФП: вводная статья
От: prVovik Россия  
Дата: 29.09.04 20:23
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, prVovik, Вы писали:


V>>Если уж и начали мерятся скоростями, то со стороны С++ должен выступать ICC. Ибо он рулит.

WH>Ну выступи. Ибо ICC у меня нет.
А у меня тоже
... << RSDN@Home 1.1.4 @@subversion >>
лэт ми спик фром май харт
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка: :)
Здравствуйте, FR, Вы писали:

FR>В последних версиях питона это практически реализовано.


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

Кстати, питон ведь тоже можно отнести к функциональным языкам.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Quintanar, Вы писали:

Q>Не ты не понял. Ты жаловался на то, что в OCaml трудно понимать программы. Так вот у них там есть P4, с помощью которого можно адаптировать синтаксис OCaml'a к своим нуждам. У них самих на нем сделана новая форма записи — т.е. изменен синтаксис языка без изменения самого языка.


Это очень интересный подход. Я с Павлом Леоновым как раз пытаюсь создать нечто-подобне дя Шарпа.

Но все же к примеру квиксорта на Хаскеле эта информация не имеет отношения.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Питон позволяет писать в функциональном стиле, было-бы желание. Что мы и видим в твоем примере. Так что ФЯ здесь причем — откуда, ты думаешь, в питоне взялись list comprehensions?


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

Я лично вижу это совмещение так: Создается некий фрэймворк для решения конретных задач. Этот фрэймворк может содержать императивный стиль. Цель этого фрэймворка свести задачу к минимуму при этом не проиграв в производительности и функциональности.

Вот только динамическая типизация Питона и его ориентированность на интерпретацию не дают ему шанса стать серьезным универсальным языком. Ну, да идейный вклад — это уже не мало.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Я вот в твоем коде не вижу императивности. Причем совсем. Ты бы для начала почитал где-нибудь, что такое "функциональность", например в comp.lang.functional FAQ. Но впрочем, что это я к тебе пристаю? Не видишь — и хорошо.


Может быть ты не заметил, что ты только что задел человека. Даж если он не прав все равно можно было бы вместо надменного тона попытаться ему объяснить в чем он не прав.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Здравствуйте, FR, Вы писали:


FR>>то есть цикл for это теперь функциональный стиль? Спасибо не знал.

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

G>Кстати, слепенький я наверно. Ну не вижу я цикла for в твоем коде. А вот list comprehensions вижу, как и отсутствие побочных эффектов.

G>
G>def qsort(aList): 
G>        if not aList: 
G>                return [] 
G>        ltList=[y for y in aList[1:] if y<aList[0]] 
G>        gtList=[y for y in aList[1:] if y>=aList[0]] 
G>        return qsort(ltList)+[aList[0]]+qsort(gtList) 
G>


Ну, вот тебе те же яйца, только в профиль на шарпе:
static void Main(string[] args)
{
    List<int> list = new List<int>(new int[]{ 2, 5, 1, 4, 3, 9, 4, 7});

    List<int> result = QuickSort<int>(list);
    result.ForEach(delegate(int elem) { Console.WriteLine(elem); });
}

static List<T> QuickSort<T>(List<T> list) where T : IComparable<T>
{
    if (list.Count <= 1)
        return list;
    T mid = list[list.Count / 2];
    List<T> ltList = list.FindAll(delegate(T elem) { return elem.CompareTo(mid) < 0; });
    List<T> eqList = list.FindAll(delegate(T elem) { return elem.CompareTo(mid) == 0; });
    List<T> gtList = list.FindAll(delegate(T elem) { return elem.CompareTo(mid) > 0; });
    return Concatenate(QuickSort<T>(ltList), eqList, QuickSort<T>(gtList));
}

static List<T> Concatenate<T>(params List<T>[] lists)
{
    List<T> result = new List<T>();
    foreach (List<T> list in lists)
        result.AddRange(list);
    return result;
}


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

G>Что характерно, если ты добавишь в любой язык встроенные списки так, как это сделано в современных ФЯ, то на нем сразу станет удобно писать в функциональном стиле. Одного не понимаю, каким именно образом это порочит "светлую идею" ФЯ?


А что ее кто-то порочил?
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>А на самом деле это один из вариантов ZF-нотации, что и есть list comprehensions. В питоне заимствовано из функциональных языков.

G>ltList = [ y | y <- tail( aList ), y < head( aList ) ]

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

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

G>Просто ты за меня выдумываешь, что я имею в виду. Прочитай comp.lang.functional FAQ, чтобы понять, что такое функциональный стиль и при каких условиях язык можно отнести к функциональному. Питон, например, вполне можно — было-бы желание.

А шарп можно? В нем ведь тоже можно в функциональном стиле писать. Причем многие концепции ФЯ успешно эмулируются. Да и на С++ тоже...

ЗЫ

Кстати, тут одна дама, автор одного из учебников, по лиспу отнесла Питон к фнкциональным языкам.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, Nick_, Вы писали:

N_>Здравствуйте, FR, Вы писали:


FR>>Угу, к сожалению функциональные языки (я сейчас ocaml ковыряю) оказались не такими удобными, вроде бы и абстракция на самом деле выше, но все равно они кажутся более далекими от человеческого мышления


N_>Это только так кажется на первый взгляд.


Ага. Я даже как-то слышал, что первый взгляд он самый верный.

Если серьезно, то речь о том и идет, что синтаксис ФЯ требует "ломать голову". Я вот для себя провожу аналогию с тем же парсингом. К примеру, арифметические выражения проще записывать как леворекурсивную граматику. Но тот же метод рекурсивного спуска требует устранение левой рекурсии. Сделать это не сложно. Получающаяся при этом граматика не намного сложнее исходной. Но при этом она крайне трудно воспринимается. Ну, привык человек рассматривать выражения как "А + Б", а не как "А +Б С". Нужна нехилая тренировка чтобы не напрягаясь воспринимать такую переделанную граматику. В общем, нужно учиться переключать мозг от обычного (применяемого в жизни) стиля мышления к "нужному". И если питон позволяет поднимать уровень абстракции не заставляя при этом человека "переключать" мозг, то это замечательно.
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: ФП: вводная статья
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.04 21:53
Оценка:
Здравствуйте, FR, Вы писали:

FR>По тестам которые ты выше привел, на другой странице я нашел тест с psyco(jit компилятор питона) у них результаты практически одинаковы с интерпретатором, у меня при включении psyco тест срабатывает в 25 раз быстрее чем интерпретируемый, если они и с остальными языками также намеряли, то доверия к ним нет никакого.


Там все еще забавнее. В ОКамле алгоритмы в императивном стиле. Возми к примеру хип-сорт. Так что... Да и редко когда код на функциональном языке оказывается сильно короче того же С. И частенько хваленый хаскель сливает по черному (например, в Spell Checker или в Word Frequency).
... << RSDN@Home 1.1.4 beta 2 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: ФП: вводная статья
От: Nick_ Россия  
Дата: 30.09.04 01:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если серьезно, то речь о том и идет, что синтаксис ФЯ требует "ломать голову". Я вот для себя провожу аналогию с тем же парсингом. К примеру, арифметические выражения проще записывать как леворекурсивную граматику. Но тот же метод рекурсивного спуска требует устранение левой рекурсии. Сделать это не сложно. Получающаяся при этом граматика не намного сложнее исходной. Но при этом она крайне трудно воспринимается. Ну, привык человек рассматривать выражения как "А + Б", а не как "А +Б С". Нужна нехилая тренировка чтобы не напрягаясь воспринимать такую переделанную граматику. В общем, нужно учиться переключать мозг от обычного (применяемого в жизни) стиля мышления к "нужному". И если питон позволяет поднимать уровень абстракции не заставляя при этом человека "переключать" мозг, то это замечательно.


Ну во первых, наверное не синтаксис требует ломать голову. Синтаксис проще некуда.
Во вторых, любые нетривиальные задачи, которые стоят перед программистами требуют "ломать голову". И от этого по словам Брукса (Мифический человеко-месяц) никуда не деться.
Ну и в третих, то, что функциональный стиль труднее воспринимается — это не правда. Часто рекурсивные программы проще. А на императивных языках, из-за того, что рекурсия неэффективно компилируется тот же алгоритм начинает напоминать грамматику в форме Грейбах (как говорите "A +B C"). Хуже от этого может и не становится, но изящность теряется.
Если бы у вас было бы математическое образование (а похоже, что оно у вас не математическое), то вы бы когда-то изучали логику и вам было бы проще "переключать мозг" в "нужную" сторону. А пока, вы мне напоминаете того, кто всю жизнь работает с грамматиками "A +B C" и так привык к этому, что "A + B" кажентся непривычным.
Re: Вопрос о конкретных примерах
От: borisman2 Киргизия  
Дата: 30.09.04 05:30
Оценка:
У меня вопрос следующий.

Я изучал ФЯ главным образом по языку Clean. Как работвют основные конструкции, что почем, я понял. Однако куда реально это применить — не знаю.

Иными словами, необходимы конкретные примеры применения ФЯ как внутри ИЯ проектов, так и в самостоятельных проектах, полностью написанных на ФЯ.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.