Re[27]: C++ vs ???
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.12.05 06:31
Оценка: 7 (1)
Здравствуйте, reductor, Вы писали:

R>Можно увидеть алгоритм, который выделяет общерекурсивные функции и раскручивает их в общем виде? (Не считая оптимистичного исполнения)

R>Который раскрутит и заинлайнит например функцию аккермана или тот же quicksort?
Гм. Насчет квиксорта я не уверен. Но попытка пощитать рекурсивно факториал константы:
cout << factorial(7);
...

int factorial (int f)
{
  return f <= 1 ? 1 : f*factorial(f-1);
}

Как минимум MS VS 7.1 вообще не будет делать вызова factorial в релизе. Вместо него в operator << будет сразу передан результат вычисления 7!.
Можно поэкспериментировать насчет передачи в нее переменной.
Но Влад говорит о том, что в общем случае инлайнится не функция, а вызов. Никакой фантастики для этого не нужно. Да, не для всех случаев удается вообще избавиться от вызова. Насчет замены хвостовой рекурсии я не в курсе.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[26]: C++ vs ???
От: Глеб Алексеев  
Дата: 13.12.05 08:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>http://en.wikipedia.org/wiki/Tail_recursion

From Wikipedia, the free encyclopedia that anyone can edit

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

Converting a call to a branch or jump in such a case is called a tail call optimization.

Но еще есть и это:

For normal, non-recursive function calls, this is usually a micro-optimization that saves little time and space, since there are not that many different functions available to call. When dealing with recursive or mutually recursive functions, however, the stack space and the number of returns saved can grow to huge numbers, since a function can call itself, directly or indirectly, a huge number of times. In fact, it often asymptotically reduces stack requirements from linear, or O(n) stack space, to constant, or O(1) stack space.

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

з.ы. В ближайшее время, скорее всего, не смогу отвечать, так что оставьте это сообщение без внимания.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[43]: C++ vs ???
От: Cyberax Марс  
Дата: 13.12.05 09:14
Оценка:
vdimas wrote:

> C>Оно будет в C++09, а пока есть в GCC и MSVC в виде __restrict.

> Я не совсем понимаю принцип действия этого предполагаемого restrict.
> Это мы как бы "обещаем" компилятору что-то?

Да, мы обещаем, что у указателей не будет aliasing'а. То есть указатель
является "владеющим" для данного блока, и никакие другие указатели (в
этой функции) не ссылаются на данные внутри этого блока.

> А кто контоллирует выполнение обещания?


Совесть программиста

> Сможет ли компилятор проконтроллировать?


В некоторых простых случаях (и во время отладки) — сможет.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[43]: C++ vs ???
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.12.05 10:55
Оценка: +1
Здравствуйте, vdimas, Вы писали:

V>Сможет ли компилятор проконтроллировать?

Гм. А ничего, что компилятор не может проконтролировать reinterpret_cast? restrict — это еще один способ для программиста дать компилятору некоторое обещание. В обмен на порождение более оптимального кода.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[43]: C++ vs ???
От: z00n  
Дата: 13.12.05 10:57
Оценка: 7 (1)
Здравствуйте, vdimas, Вы писали:

V>Я не совсем понимаю принцип действия этого предполагаемого restrict. Это мы как бы "обещаем" компилятору что-то? А кто контоллирует выполнение обещания?


Хороший вопрос!

There are three reasons that "restrict" isn't part of C++ already:

— The committee felt that enough was being added to C++ already so that new features should be minimized. An isolated feature such as "restrict" could and should be tried out in the communities in which it is most needed before it is added it to Standard C++.
The "restrict" feature cannot in general be verified to be safe by a compiler. The committee felt that more work was needed to see if a better-behaved alternative could be found.
— The C++ Standard Library provides valarray as a mechanism to support high-performance Fortran-like vector computation.

The reasons for reconsidering "restrict" are:

— "restrict" appears to be becoming increasingly useful as more processors acquire architectural features such as long pipelines and parallel execution. When "restrict" was first discussed by the C++ committee, maybe 5 percent of all processors used by the -- C++ community had the high-performance features that made "restrict" valuable. Today, I suspect that percentage is closer to 95 percent.
— We have not (to the best of my knowledge) found an alternative that lends itself to static type checking in a general C++ environment.
— The valarray part of the C++ Standard Library has not yet taken hold on a significant scale. If it does, valarray will have no problem coexisting with "restrict." Thus, the bigger issue is the coordination between the C and C++ national and ISO committees. However, every vendor of C and C++ implementations face a dilemma between conformance to a divergent standard and making the full set of facilities available in all contexts.

Interview With Bjarne Stroustrup http://www.research.att.com/~bs/devXinterview.html


А вот о событиях 20-летней давности, цитата из D&E:

To contrast, the committee has rejected many proposals. For example:

Several proposals for direct support for concurrency
Renaming of inherited names (sec12.8)
Keyword arguments (sec6.5.1)
Several proposals for slight modifications of the data hiding rules
Restricted pointers (``son of noalias'') (sec6.5.2)
Exponentiation operator (sec11.5.2)
Automatically generated composite operators
User­defined operator.() (sec11.5.2)
Nested functions
Binary literals
General initialization of members within a class declaration.

Bjarne Stroustrup:
The Design and Evolution of C++

Re[44]: C++ vs ???
От: vdimas Россия  
Дата: 13.12.05 10:58
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

>> А кто контоллирует выполнение обещания?


C>Совесть программиста


Да я как бы на это и намекал
Т.е. ты должен понимать, что в реальной жизни это — грабли. Т.е. не покатит. Пускай это останется для C, у него и так все на машинном уровне, но я был бы против такого в C++.
Re[45]: C++ vs ???
От: Cyberax Марс  
Дата: 13.12.05 12:14
Оценка:
vdimas wrote:

> C>Совесть программиста

> Да я как бы на это и намекал
> Т.е. ты должен понимать, что в реальной жизни это — грабли. Т.е. не
> покатит. Пускай это останется для C, у него и так все на машинном
> уровне, но я был бы против такого в C++.

Нет, почему же. Тот же Blitz++ вполне успешно использует restrict (в
своих воплощениях в виде __restrict и __atribute__ restrict).

Да и нужен он обычно в небольших функциях типа memmove.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[46]: C++ vs ???
От: reductor  
Дата: 13.12.05 13:06
Оценка: +1
Здравствуйте, VladD2, Вы писали:

R>>Эти фантазии относятся к окамлу не больше, чем к С++.


VD>Ай как не хорошо. Опять вместо аргументации нечестные приемы. Назваем чужие слова "фантазией" без малейших на то оснований.


То, что окамл нацелен на работу со списками — чистой воды фантазии, да девичьи мечты.

VD>И что мне на него смотреть? Ты напиши эффективную реализацю быстрой сортировки не массивах да с выборкой разделителя из середины, а потом сравним этот код с тем самым С++ и исходным вариантом на Окамле. Если он будет таким же кратким как исходный, я сниму шляпу. А если он окажется медленее или длинее, то извини, но ты докажешь свою не правоту.


Вот, минут за 20 на коленке mergesort (устойчивая O(n log n) сортировка) in-place на окамле. Почти не использует никаких библиотечных функций:
open Array;;
let msort xs = 
    let rec sort bgn fin =
        let rec merge bgn mid fin =
            let shift () = blit xs bgn xs (bgn + 1) (mid - bgn) in
            if mid >= fin || bgn >= mid then ()
            else let x, y = xs.(bgn), xs.(mid) in
                 let change () = (shift (); xs.(bgn) <- y) in
                 let bgn, mid = if x <= y then (bgn + 1, mid)
                                else (change (); (bgn, mid + 1))
                 in merge bgn mid fin in
        if fin - bgn <= 1 then ()
        else let mid = (fin + bgn) / 2 in
             let () = sort bgn mid; sort mid fin
             in merge bgn mid fin
    in sort 0 (length xs);;

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


VD>Ну, тебе виднее. Я в Окамле делетант.

Я правильно вас понимаю, что вы считаете нормальным — являсь дилетантом в языке выдавать агрессивные суждения о нем и еще потом отстаивать свои фантазии?
Если так, дальнейшая дискуссия не имеет смысла.

VD>Но вот в совершенно не функциональном Руби код получается не более длинный чем в Окамле, а ведь "матчить" то он вроде не умеет.


Я правильно вас понимаю, что вы предлагаете всем отказаться от окамла и С++ в пользу руби?

R>>Я все сказал на эту тему, повторяться не буду.

R>>Еще не хватало участвовать в спорах на уровне первокурсников.

VD>Ты пока что споришь на уровне палитиков из ящика. Громко, зажигательно, оскорбительно... но бестолково и не честно. Все аргументы "делетантство", "первокурсник" и т.п. Называется это одним емким и красочным словом — демогогия. И тут ты не лучший. Тут есть перцы которые ей родимой кого хочешь куда хочешь заткнут если их вовремя не остановить. :)


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

VD>В общем, общаться на уровне "делетантсва" и "первокурсников" я не намерен. Отвечая таким образом на технический вопрос ты рассписывашся в своей неправоте. Мне этого ответа достаточно. Но если вдруг захочется дейсвительно аргументировано ответить, то я буду очень рад.


Интересно бы еще услышать в какой неправоте я здесь рассписываюсь.
Re[43]: C++ vs ???
От: reductor  
Дата: 13.12.05 13:10
Оценка: :))) :)
Здравствуйте, VladD2, Вы писали:


VD>И, что, после этого я таки получу полиморфный "+" как в "обычных" языках? И при этом ничего не посыпется? И приоритеты останутся?...


Нет, разверзгнутся хляви небесные, наступит армагеддон и мы все очутимся в геене огненной.
Re[30]: C++ vs ???
От: reductor  
Дата: 13.12.05 13:18
Оценка:
Здравствуйте, VladD2, Вы писали:

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


R>>Или показываем алгоритм (даем математически строгое описание) или тема закрыта раз и навсегда — про "стоит денег" и "скомпилируй увидишь".


VD>А, ну, тогда тема закрыта, так как ни одно "математически строгое описание" ты не дал.


Описание чего, простите _я_ должен дать?

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


Давайте не будем сейчас про секретные ЦРУшные алгоритмы. Это из области ЦРУшного числа пи, которое равно ровно трем.


R>>Поясню почему я столь настойчив — у меня есть все основания считать, что такого алгоритма не существует и не может существовать.


VD>И есть "математически строгое описание" этого основания?


Да. Теория автоматов на этом настаивает.

R>>Нет способа определить общерекурсивность той или иной функции.

VD>Что значит "общерекурсивность"?

Ого.
первая ссылка в яндексе на поиск этого слова: http://ric.uni-altai.ru/Fundamental/teor-alg/upr15/upr15-2.htm

Кстати я прекращаю обсуждение с вами этой темы.

R>>А разговор о только хвостовой смысла не имеет. Любая хвостовая рекурсия заменяется циклом и наоборот и ни о каком выигрыше здесь ни с одной ни с другой стороны речи идти не может.


VD>Хм. Теоритически — да. На практике 99% комиляторов ИЯ этого не делают и разница на рекурсивных вызовах вроде тех что идут в примерах к ФЯ огромна.


И что? Им это не нужно и приносит больше проблем, чем пользы (со stacktrace например)

VD>Ты что доказать то хочешь? Ведь если с тобой согласиться и не считать устранине рекусрии оптимизацией, то зачем же ты тогда привел сравнение где у ФЯ рекурсия устраняется, а у ИЯ нет?


я привел сравнение?!
Я все понимаю, но вы меня с кем-то путаете.
Re[43]: C++ vs ???
От: reductor  
Дата: 13.12.05 13:37
Оценка:
Здравствуйте, vdimas, Вы писали:


V>Некоторые ФЯ подерживают и обычные packed array, но над эти массивом быстрая сортировка будет выглядеть по-другому. В то же самое время сортировка связанного списка и на С++ была бы практически такой же, как приведенная.


Все ФЯ поддерживают mutable arrays. что касается по-другому — то можно и так же, но это неэффективно — матчить массив как cons cells — это и неэффективно и бессмысленно.

V>Т.е. К классу языка ЯП этот вопрос не лежит никаким боком.

V>Приведенный код был содран из первой страницы туториала по OCalm, и его авторы, приводя такие вещи, явно лукавят, умалчивая особенности такой реализации.

Естественно. было лень руками набирать — вставил то, что первое попалось в гугле. сам бы я написал скорее так:
open List;;
let rec qsort = function
     | [] -> []
     | (x::xs) -> let left,right = partition ((>) x) xs
                  in qsort left @ x::qsort right;;


V>А вот и мой "перевод" на С++:

V>Красота... Не хуже OCalm-a. :)))

Не так наглядно и главное — в окамле без всяких лишних библиотек, вспомогательных функций и шаблонов :)

V>Чтобы конкатенация занимала константное время я представил список в виде пары — указателя на первый и последний элемент. В исходном примере использовалась List.partition я сделал аналогичный метод split(predicate, value), вот код целиком вместе с декларациями примитивов:

V>
#include <iostream>
#include <functional
// ААААА. сколько кода поскипнуто :)
Re[33]: ocamlopt и MSVC - кто быстрее?
От: reductor  
Дата: 13.12.05 13:47
Оценка: :)
Здравствуйте, VladD2, Вы писали:


VD>Видел как тут народ на Оберон реагирует? Это потому, что Губанов палку перегнул. Вот тоже будет с Окамлом если его так "поддерживать". Пойми, тут на форуме почти все сочувствующие функциональному подходу вообще и Окамлу в частности. А гиперпропаганда просто отталкивает.


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


VD>Мы с удовольствием послушаем интересные мысли. Даже с удоволствием поспорим в честном споре. Но когда начинается пиар и фанатизм, то хочется только противодействовать.


Да мне в общем-то даже спорить неинтересно. Мне интересно узнавать что-то новое для себя. Затем я здесь.

VD>На этом форуме давно извесно кто за что ратует. Я вот дотнет пропагандирую, ПК плюсы, Губанов Оберон, Гапертон и т.п. ФЯ. Каждый по своему прав. И каждый дает остальным некоторые новые знания. Потому мы тут сидим, а не разбежались по углам или не перенабили друг-другу морду. Так что присоеденяйся. :)


Да ну, ратовать еще за что-то. Не хочу.
Я программировать люблю. Учиться люблю.
Если кто-то спрашивает о чем-то, в чем я разбираюсь — могу ответить.
Ратовать и пропагандировать — не люблю.
Re[44]: C++ vs ???
От: vdimas Россия  
Дата: 13.12.05 22:00
Оценка:
Здравствуйте, reductor, Вы писали:

V>>А вот и мой "перевод" на С++:

V>>Красота... Не хуже OCalm-a.

R>Не так наглядно и главное — в окамле без всяких лишних библиотек, вспомогательных функций и шаблонов


Ну как же, а partition, а базовые представления списков? Все лишнее у тебя уже есть. Сами агрегаты вставлены в язык. В С/С++ никакие агрегаты в язык не вставлены. Кому надо — вставляет оные из стандартной бибиотеки.

V>>Чтобы конкатенация занимала константное время я представил список в виде пары — указателя на первый и последний элемент. В исходном примере использовалась List.partition я сделал аналогичный метод split(predicate, value), вот код целиком вместе с декларациями примитивов:

V>>
R>#include <iostream>
R>#include <functional
R>// ААААА. сколько кода поскипнуто :)
R>


Блин, да я же специально STL не юзал, кроме примитива pair<T1, T2>, чтобы показать трудоемкость решения с 0-ля.
Т.е., очень эффективные, приближенные к "машинной" реализации список я нарисовал прямо при тебе, т.к. он не был встроен в язык (слава богу). Любые другие задачи могут "идти дальше", не описывая все это повторно, разумеется. Не верю, что ты этого не понимаешь.

СПонятное дело, что с использованием стандартной либы я бы просто написал qsort(array, array+len);
Re[5]: C++ vs ???
От: c-smile Канада http://terrainformatica.com
Дата: 13.12.05 22:43
Оценка:
Здравствуйте, alexeiz, Вы писали:

CS>>>>D как язык для UI лучше чем C++ скажем в разы. Это я со всей отвественностью

CS>>>>могу сказать.

A>>>А причины не трудно описать? По пунктам и конкретно. А то не очень-то верится.


CS>>1) GC. GC helps a lot managing DOM/windows/elements structure. This is huge in fact. Simplifies significantly code. Makes it clean and compact thus more robust.


A>Мне кажется, что это просто аргумент в пользу GC, а не конкретно GC для программирования UI. В UI обычно у каждого элемента есть свой owner, который его и освобождает. Так устроено в MFC, QT, да и даже в старом Motif'е. Может быть внутри фреймвока и легче отслеживать время жизни элементов с помощью GC, но для пользователя это никогда не было проблемой.


owner — да но так же есть и reference на parent. Т.е. имеем циклическую ссылку
которую естесственным образом в C++ не решить.


A>Кстати, о проблемах с GC в UI. Бывает и так: пользователь открывает новое окно/диалог, который отъедает кучу ресурсов. Пользователь закончил свою работу с окном, закрыл его. А ресурсы всё ещё в памяти. GC ни сном ни духом не ведает, что при закрытии окна нужно что-то освободить. А пользователь жалуется. Мол окно уже закрыто, почему программа до сих пор столько памяти держит? И вот GC ждёт пока другое такое ресурсопрожорливое окно откроется, тогда он сразу спохватится, начнёт освобождать. А окно в это время тормозит.


Какое отношение имеет "ресурсопрожорливое окно" к GC?


A>Да и на C++ это дело можно сделать, так как GC имеются, а в большинстве случаев smart pointer'ов дольжно быть достаточно.


В теории да. На практике нет.

A>Поэтому тут по возможностям D не перекрывает C++.


Перекрывает именно наличием встроенного GC.

CS>>2) Closures/Delegates. This in fact is not so critical as I am using sinking/bubbling. Let's say it is nice to have feature — allows to simplify code and make it more understandable an regular.


A>boost::function, boost::signal? win32 gui generics использует этот же механизм. C++ не нужно иметь delegates в языке, т.к. они есть в библиотеке.


к сожалению они не завязяны на GC.
Система UI объектов и их ссылок как правило имеет очень сложную струтуру с циклами.
Иногда в принципе нельзя отследить кто кого держит.
Для таких ситуаций GC это то что доктор прописал. Зело упрощает все эти танцы со смарт указателями.


CS>>3) Properties (getters/setters). Ideally reduces twice methods you need to remember. Again, it is about simplification.


A>Если бы ты упомянул свойства для создания компонент с их последующем использовании в дизайнере, то это бы имело смысл. А иначе свойства представляют спорный вопрос, опять же не имеющий отношение к UI per se.


Дело вкуса конечно.

CS>>4) There are more features in D helping UI development e.g. mixins and templates parametrized by character strings, etc., I'll skip them here.


A>Миксины есть в C++. Curiously recurring template pattern, policies — это всё имеет отношение к миксинам.


Это не те mixins. Вернее не только те.

A>Может быть параметризация шаблонов строками и помогает. Об этом судить не берусь.


CS>>Use of Java for massive UI development has one and big benefit — isolation between logic and system low level and critical functions. This is sort of critical for development in teams.


A>Здесь не совсем понятно, что ты имеешь ввиду, и каким образом это подкрепляет аргумент в пользу Java для программирования UI.


Я имею ввиду то что код взаимодействующий и знающий про handles & resources
живет в native C методах ничего не знающих про GC — они "GC statless".
Код же связывающий компоненты в единое целое это Java.

CS>>And again Java has good set of design tools. Intellisense is a real tool increasing productivity.


A>You mean UI design tools? К языку это имеет опоследовательное отношение. Для C++ тоже есть UI design tools.


К языку да — опосредованное. Но в компонентном UI design reflection является бенефитом.
Re[28]: C++ vs ???
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.12.05 23:00
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Как минимум MS VS 7.1 вообще не будет делать вызова factorial в релизе. Вместо него в operator << будет сразу передан результат вычисления 7!.


Ну, незнаю. Может я что-то делаю не так, но вот что я получил под отладчиком (Release VS 2005):
__forceinline int __fastcall factorial (int f)
{
00401000  push        esi  
00401001  mov         esi,ecx
  return f <= 1 ? 1 : f*factorial(f-1);
00401003  cmp         esi,1 
00401006  jg          factorial+0Fh (40100Fh) 
00401008  mov         eax,1 
0040100D  pop         esi
}
0040100E  ret
  return f <= 1 ? 1 : f*factorial(f-1);
0040100F  lea         ecx,[esi-1] 
00401012  call        factorial (401000h) 
00401017  imul        eax,esi 
0040101A  pop         esi
}
0040101B  ret


Так что как раз VC похоже тут звезд с неба не хватает.

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


Именно. Да и в чем тут фантастика может быть?
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[29]: C++ vs ???
От: Костя Ещенко Россия  
Дата: 14.12.05 03:56
Оценка: 31 (3)
Здравствуйте, VladD2, Вы писали:

S>>Как минимум MS VS 7.1 вообще не будет делать вызова factorial в релизе. Вместо него в operator << будет сразу передан результат вычисления 7!.


VD>Ну, незнаю. Может я что-то делаю не так, но вот что я получил под отладчиком (Release VS 2005):


[]

VD>Так что как раз VC похоже тут звезд с неба не хватает.


Ты, видимо, не установил #pragma inline_recursion(on). А вычислит ли vc константу, зависит от значения N в #pragma inline_depth(N). Т.к. по умолчанию N=8, то 7! вычисляется в константу.

Но интересно не это. Интересно, что vc7.1 устраняет хвостовую рекурсию. Переписываем factorial в хвостово-рекурсивном виде:
unsigned __fastcall fact_(unsigned n, unsigned accum)
{
  return n > 1 ? fact_(n-1, n*accum) : accum;
}

unsigned factorial(unsigned n)
{
  return fact_(n, 1);
}

и получаем цикл:
unsigned __fastcall fact_(unsigned n, unsigned accum)
{
    return n > 1 ? fact_(n-1, n*accum) : accum;
00401000  cmp         ecx,1 
00401003  mov         eax,edx 
00401005  jbe         fact_+12h (401012h) 
00401007  mov         edx,ecx 
00401009  imul        edx,eax 
0040100C  dec         ecx  
0040100D  jmp         fact_ (401000h) 
}
00401012  ret
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[47]: C++ vs ???
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 14.12.05 06:52
Оценка:
Здравствуйте, reductor, Вы писали:

VD>>Но вот в совершенно не функциональном Руби код получается не более длинный чем в Окамле, а ведь "матчить" то он вроде не умеет.


R>Я правильно вас понимаю, что вы предлагаете всем отказаться от окамла и С++ в пользу руби?


Не-а. Влад -- он за .NET и C#.
А переход на Ruby -- это я. И не вместо C++, а вместе с C++.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[45]: C++ vs ???
От: reductor  
Дата: 14.12.05 12:02
Оценка:
Здравствуйте, vdimas, Вы писали:

R>>Не так наглядно и главное — в окамле без всяких лишних библиотек, вспомогательных функций и шаблонов :)


V>Ну как же, а partition, а базовые представления списков? Все лишнее у тебя уже есть. Сами агрегаты вставлены в язык. В С/С++ никакие агрегаты в язык не вставлены. Кому надо — вставляет оные из стандартной бибиотеки.


Представление списков — это _только_ окамловские типы :)
Все очень просто:

(* список - это всего лишь  *)
type 'a list = Nil | Cons of 'a * 'a list

(* "агрегаты" ;) *)
let (::) fst snd = Cons (fst, snd);;

let rec (@) l1 l2 =
  match l1 with
    [] -> l2
  | hd :: tl -> hd :: (tl @ l2)

let partition p l =
  let rec part yes no = function
  | [] -> (rev yes, rev no)
  | x :: l -> if p x then part (x :: yes) no l else part yes (x :: no) l in
  part [] [] l

(* ну а точнее родной окамловский список - это (определение a-la haskell): *)
type 'a list = [] | 'a :: 'a list


Алгебраические типы — они огого.
Дело не в синтаксисе. Тут именно в системе типов (вспомним еще что они сами выводятся) мощь.

V>Блин, да я же специально STL не юзал, кроме примитива pair<T1, T2>, чтобы показать трудоемкость решения с 0-ля.

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

Очень даже понимаю
Сам не люблю трудоемкость ;)
Re[31]: C++ vs ???
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.12.05 18:53
Оценка: 8 (2)
Здравствуйте, reductor, Вы писали:

R>Описание чего, простите _я_ должен дать?


Своим утверждениям.

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


R>Давайте не будем сейчас про секретные ЦРУшные алгоритмы. Это из области ЦРУшного числа пи, которое равно ровно трем.


А кто говорит о сикретности? Это обемистые коммерческие алгоритмы. Только и всего. "Куча кода", понимаешь?

Вобщем, вот тебе код который будучи скомпилированным на VC8 производит инлайнинг рекурсивной функции:
#include "stdafx.h"

#pragma inline_recursion(on)
#pragma inline_depth(2)

__forceinline int __fastcall factorial (int f)
{
  return f <= 1 ? 1 : f*factorial(f-1);
}

void Print(int i)
{
    printf("%d\n", i);
}

__declspec(noinline) void Test()
{
    Print(factorial(7));
}

void main()
{
    __asm int 3;
    Test();
}

Резульата получаетс следующим:
__forceinline int __fastcall factorial (int f)
{
00401000  push        ecx  
  return f <= 1 ? 1 : f*factorial(f-1);
00401001  cmp         ecx,1 
00401004  mov         dword ptr [esp],ecx 
00401007  jg          factorial+10h (401010h) 
00401009  mov         eax,1 
}
0040100E  pop         ecx  
0040100F  ret              
00401010  push        ebp  
  return f <= 1 ? 1 : f*factorial(f-1);
00401011  lea         ebp,[ecx-1] 
00401014  cmp         ebp,1 
00401017  jg          factorial+24h (401024h) 
00401019  mov         eax,1 
0040101E  imul        eax,ecx 
00401021  pop         ebp  
}
00401022  pop         ecx  
00401023  ret              
  return f <= 1 ? 1 : f*factorial(f-1);
00401024  push        ebx  
00401025  lea         ebx,[ebp-1] 
00401028  cmp         ebx,1 
0040102B  jg          factorial+3Ch (40103Ch) 
0040102D  mov         eax,1 
00401032  imul        eax,ebp 
00401035  pop         ebx  
00401036  imul        eax,ecx 
00401039  pop         ebp  
}
0040103A  pop         ecx  
0040103B  ret              
  return f <= 1 ? 1 : f*factorial(f-1);
0040103C  push        edi  
0040103D  lea         edi,[ebx-1] 
00401040  cmp         edi,1 
00401043  jg          factorial+58h (401058h) 
00401045  mov         eax,1 
0040104A  imul        eax,ebx 
0040104D  imul        eax,ebp 
00401050  pop         edi  
00401051  imul        eax,ecx 
00401054  pop         ebx  
00401055  pop         ebp  
}
00401056  pop         ecx  
00401057  ret              
  return f <= 1 ? 1 : f*factorial(f-1);
00401058  push        esi  
00401059  lea         esi,[edi-1] 
0040105C  cmp         esi,1 
0040105F  jg          factorial+78h (401078h) 
00401061  mov         eax,1 
00401066  imul        eax,edi 
00401069  imul        eax,ebx 
0040106C  imul        eax,ebp 
0040106F  pop         esi  
00401070  imul        eax,ecx 
00401073  pop         edi  
00401074  pop         ebx  
00401075  pop         ebp  
}
00401076  pop         ecx  
00401077  ret              
  return f <= 1 ? 1 : f*factorial(f-1);
00401078  lea         ecx,[esi-1] 
0040107B  call        factorial (401000h) 
00401080  imul        eax,esi 
00401083  imul        eax,edi 
00401086  mov         ecx,dword ptr [esp+10h] 
0040108A  imul        eax,ebx 
0040108D  imul        eax,ebp 
00401090  pop         esi  
00401091  imul        eax,ecx 
00401094  pop         edi  
00401095  pop         ebx  
00401096  pop         ebp  
}
00401097  pop         ecx  
00401098  ret

Причем, если задать inline_depth() в 5 и более, то компилятор вообще вычисляет значение функции во время компиляции и подставляет в код результат.

R>>>Поясню почему я столь настойчив — у меня есть все основания считать, что такого алгоритма не существует и не может существовать.


VD>>И есть "математически строгое описание" этого основания?


R>Да. Теория автоматов на этом настаивает.


Теория автоматов "настаивается" на том, что ты во что-то там поверить не можешь? Ну-ну.

R>>>Нет способа определить общерекурсивность той или иной функции.

VD>>Что значит "общерекурсивность"?

R>Ого.

R>первая ссылка в яндексе на поиск этого слова: http://ric.uni-altai.ru/Fundamental/teor-alg/upr15/upr15-2.htm

Там термин "общерекурсивность" отсуствует как класс.

R>Кстати я прекращаю обсуждение с вами этой темы.


Да, это понятно. Это такой стиль общения.

R>И что? Им это не нужно и приносит больше проблем, чем пользы (со stacktrace например)


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

R>я привел сравнение?!

R>Я все понимаю, но вы меня с кем-то путаете.

А, ну, да. Общее помешательство.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[30]: C++ vs ???
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.12.05 18:53
Оценка:
Здравствуйте, Костя Ещенко, Вы писали:

КЕ>Ты, видимо, не установил #pragma inline_recursion(on). А вычислит ли vc константу, зависит от значения N в #pragma inline_depth(N). Т.к. по умолчанию N=8, то 7! вычисляется в константу.


Да и при 5 тоже константу дает. Спасибо!

А вот при 2 он таки делает раворот тела функции.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.