Здравствуйте, 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
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
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.
Это уже ближе к телу. Автор все время твердит о стеке и адресах возврата, как будто альтернативных реализаций ЯП не существует. И о чем автор не говорит, так это о том, что наличие хвостовой рекурсии изменяет семантику программ, не имеющих ограничения на глубину рекурсии. При отсутствии хвостовой рекурсии получаем аварийное завершение, при ее наличии — сколь угодно долгий цикл. Хотите такое преобразование называть оптимизацией — пожалуйста.
з.ы. В ближайшее время, скорее всего, не смогу отвечать, так что оставьте это сообщение без внимания.
vdimas wrote:
> C>Оно будет в C++09, а пока есть в GCC и MSVC в виде __restrict. > Я не совсем понимаю принцип действия этого предполагаемого restrict. > Это мы как бы "обещаем" компилятору что-то?
Да, мы обещаем, что у указателей не будет aliasing'а. То есть указатель
является "владеющим" для данного блока, и никакие другие указатели (в
этой функции) не ссылаются на данные внутри этого блока.
> А кто контоллирует выполнение обещания?
Совесть программиста
> Сможет ли компилятор проконтроллировать?
В некоторых простых случаях (и во время отладки) — сможет.
Здравствуйте, vdimas, Вы писали:
V>Сможет ли компилятор проконтроллировать?
Гм. А ничего, что компилятор не может проконтролировать reinterpret_cast? restrict — это еще один способ для программиста дать компилятору некоторое обещание. В обмен на порождение более оптимального кода.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, 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.
А вот о событиях 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
Userdefined operator.() (sec11.5.2)
Nested functions
Binary literals
General initialization of members within a class declaration.
Bjarne Stroustrup:
The Design and Evolution of C++
Здравствуйте, Cyberax, Вы писали:
>> А кто контоллирует выполнение обещания?
C>Совесть программиста
Да я как бы на это и намекал
Т.е. ты должен понимать, что в реальной жизни это — грабли. Т.е. не покатит. Пускай это останется для C, у него и так все на машинном уровне, но я был бы против такого в C++.
vdimas wrote:
> C>Совесть программиста > Да я как бы на это и намекал > Т.е. ты должен понимать, что в реальной жизни это — грабли. Т.е. не > покатит. Пускай это останется для C, у него и так все на машинном > уровне, но я был бы против такого в C++.
Нет, почему же. Тот же Blitz++ вполне успешно использует restrict (в
своих воплощениях в виде __restrict и __atribute__ restrict).
Да и нужен он обычно в небольших функциях типа memmove.
Здравствуйте, 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>В общем, общаться на уровне "делетантсва" и "первокурсников" я не намерен. Отвечая таким образом на технический вопрос ты рассписывашся в своей неправоте. Мне этого ответа достаточно. Но если вдруг захочется дейсвительно аргументировано ответить, то я буду очень рад.
Интересно бы еще услышать в какой неправоте я здесь рассписываюсь.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, reductor, Вы писали:
R>>Или показываем алгоритм (даем математически строгое описание) или тема закрыта раз и навсегда — про "стоит денег" и "скомпилируй увидишь".
VD>А, ну, тогда тема закрыта, так как ни одно "математически строгое описание" ты не дал.
Описание чего, простите _я_ должен дать?
VD>Что до алгоритма инлайнинга, то это нехилый алгоритм и так вот тебе его никто не покажет. Ну, а как это делать в принципе ты и сам должен поянть. Вызовы заменяются на циклы и goto. Тело копируется некоторое количество раз, чтобы переход влиял по меньше и т.п.
Давайте не будем сейчас про секретные ЦРУшные алгоритмы. Это из области ЦРУшного числа пи, которое равно ровно трем.
R>>Поясню почему я столь настойчив — у меня есть все основания считать, что такого алгоритма не существует и не может существовать.
VD>И есть "математически строгое описание" этого основания?
Да. Теория автоматов на этом настаивает.
R>>Нет способа определить общерекурсивность той или иной функции. VD>Что значит "общерекурсивность"?
Кстати я прекращаю обсуждение с вами этой темы.
R>>А разговор о только хвостовой смысла не имеет. Любая хвостовая рекурсия заменяется циклом и наоборот и ни о каком выигрыше здесь ни с одной ни с другой стороны речи идти не может.
VD>Хм. Теоритически — да. На практике 99% комиляторов ИЯ этого не делают и разница на рекурсивных вызовах вроде тех что идут в примерах к ФЯ огромна.
И что? Им это не нужно и приносит больше проблем, чем пользы (со stacktrace например)
VD>Ты что доказать то хочешь? Ведь если с тобой согласиться и не считать устранине рекусрии оптимизацией, то зачем же ты тогда привел сравнение где у ФЯ рекурсия устраняется, а у ИЯ нет?
я привел сравнение?!
Я все понимаю, но вы меня с кем-то путаете.
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
// ААААА. сколько кода поскипнуто :)
VD>Видел как тут народ на Оберон реагирует? Это потому, что Губанов палку перегнул. Вот тоже будет с Окамлом если его так "поддерживать". Пойми, тут на форуме почти все сочувствующие функциональному подходу вообще и Окамлу в частности. А гиперпропаганда просто отталкивает.
Я в общем уже говорил это — я никого и ничего тут не поддерживаю и не пропагандирую.
Я не являюсь фанатом или апологетом какого-либо языка, платформы или чего-то подобного. Я всего лишь отвечаю на вопросы. Иногда спрашиваю. Если тут завтра все возненавидят окамл, оберон, хаскель, смоллтолк или вижуал бейсик — мне все равно.
VD>Мы с удовольствием послушаем интересные мысли. Даже с удоволствием поспорим в честном споре. Но когда начинается пиар и фанатизм, то хочется только противодействовать.
Да мне в общем-то даже спорить неинтересно. Мне интересно узнавать что-то новое для себя. Затем я здесь.
VD>На этом форуме давно извесно кто за что ратует. Я вот дотнет пропагандирую, ПК плюсы, Губанов Оберон, Гапертон и т.п. ФЯ. Каждый по своему прав. И каждый дает остальным некоторые новые знания. Потому мы тут сидим, а не разбежались по углам или не перенабили друг-другу морду. Так что присоеденяйся. :)
Да ну, ратовать еще за что-то. Не хочу.
Я программировать люблю. Учиться люблю.
Если кто-то спрашивает о чем-то, в чем я разбираюсь — могу ответить.
Ратовать и пропагандировать — не люблю.
Здравствуйте, reductor, Вы писали:
V>>А вот и мой "перевод" на С++: V>>Красота... Не хуже OCalm-a.
R>Не так наглядно и главное — в окамле без всяких лишних библиотек, вспомогательных функций и шаблонов
Ну как же, а partition, а базовые представления списков? Все лишнее у тебя уже есть. Сами агрегаты вставлены в язык. В С/С++ никакие агрегаты в язык не вставлены. Кому надо — вставляет оные из стандартной бибиотеки.
V>>Чтобы конкатенация занимала константное время я представил список в виде пары — указателя на первый и последний элемент. В исходном примере использовалась List.partition я сделал аналогичный метод split(predicate, value), вот код целиком вместе с декларациями примитивов: V>>
Блин, да я же специально STL не юзал, кроме примитива pair<T1, T2>, чтобы показать трудоемкость решения с 0-ля.
Т.е., очень эффективные, приближенные к "машинной" реализации список я нарисовал прямо при тебе, т.к. он не был встроен в язык (слава богу). Любые другие задачи могут "идти дальше", не описывая все это повторно, разумеется. Не верю, что ты этого не понимаешь.
СПонятное дело, что с использованием стандартной либы я бы просто написал qsort(array, array+len);
Здравствуйте, 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 является бенефитом.
Здравствуйте, 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, 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 в хвостово-рекурсивном виде:
Здравствуйте, reductor, Вы писали:
VD>>Но вот в совершенно не функциональном Руби код получается не более длинный чем в Окамле, а ведь "матчить" то он вроде не умеет.
R>Я правильно вас понимаю, что вы предлагаете всем отказаться от окамла и С++ в пользу руби?
Не-а. Влад -- он за .NET и C#.
А переход на Ruby -- это я. И не вместо C++, а вместе с C++.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, 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>Т.е., очень эффективные, приближенные к "машинной" реализации список я нарисовал прямо при тебе, т.к. он не был встроен в язык (слава богу). Любые другие задачи могут "идти дальше", не описывая все это повторно, разумеется. Не верю, что ты этого не понимаешь.
Здравствуйте, reductor, Вы писали:
R>Описание чего, простите _я_ должен дать?
Своим утверждениям.
VD>>Что до алгоритма инлайнинга, то это нехилый алгоритм и так вот тебе его никто не покажет. Ну, а как это делать в принципе ты и сам должен поянть. Вызовы заменяются на циклы и goto. Тело копируется некоторое количество раз, чтобы переход влиял по меньше и т.п.
R>Давайте не будем сейчас про секретные ЦРУшные алгоритмы. Это из области ЦРУшного числа пи, которое равно ровно трем.
А кто говорит о сикретности? Это обемистые коммерческие алгоритмы. Только и всего. "Куча кода", понимаешь?
Вобщем, вот тебе код который будучи скомпилированным на VC8 производит инлайнинг рекурсивной функции:
__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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Костя Ещенко, Вы писали:
КЕ>Ты, видимо, не установил #pragma inline_recursion(on). А вычислит ли vc константу, зависит от значения N в #pragma inline_depth(N). Т.к. по умолчанию N=8, то 7! вычисляется в константу.
Да и при 5 тоже константу дает. Спасибо!
А вот при 2 он таки делает раворот тела функции.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.