4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|||||||||||
1 | |||||||||||
Рекурсия vs цикл с точки зрения производительности29.08.2015, 18:43. Показов 8131. Ответов 26
Метки нет (Все метки)
Здравствуй, дорогой форум!
Написал алгоритм для отображения десятичных чисел в двоичной системе в двух вариантах: с использование рекурсии и цикла: Первый вариант(используем рекурсию):
0
|
29.08.2015, 18:43 | |
Ответы с готовыми решениями:
26
Выбор встроенной базы данных с точки зрения производительности Как лучше реализовать сервер с точки зрения производительности? Drawingvisual или Usercontrol: какой вариант будет реализовать правильней с точки зрения производительности Если два метода выполняют одно и то же - с точки зрения программы, но разное - с точки зрения логики? |
1375 / 519 / 72
Регистрация: 21.07.2015
Сообщений: 1,304
|
||||||
29.08.2015, 19:01 | 2 | |||||
Вообще - да, вызов процедуры занимает время (особенно если у функции куча входных параметров). Но тут еще все зависит от того как "развернуть" рекурсию, можно так, что трудоемкость алгоритма станет другой.
1
|
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|
29.08.2015, 19:28 [ТС] | 3 |
Хех...
Да, такие мы маньяки, лёгкие пути - это не для нас! Если серьёзно, то ваш код, конечно, выглядит куда более лаконично, чем мой том войны и мира, но мне он непонятен с моими текущими знаниями языка. Написал, как смог.) В любом случае на мой вопрос вы ответили, так что ловите спасибо! shmkv P.S. А как называется такой оператор: ">>="? По символам гугл ничего не находит. Хотел бы понять ваш код.
0
|
29.08.2015, 19:32 | 4 |
Alexey104, ссылаясь на материал из книги Дейтелов по Си++, могу сказать что, итеративный (циклический) метод вычисления, как правило, менее ресурсоемкий => более быстрый. Но бывают такие случаи, когда решение задачи рекурсивным образом бывает проще с точки зрения объема кода и его отладки. Например, создание динамических структур данных по типу дерева.
0
|
29.08.2015, 19:37 | 6 |
Побитовый сдвиг вправо с присваиванием, как правило, такие конструкции заимствованы из чистого Си. Ими, по возможности, лучше не пользоваться в целях успешной переносимости программ.
1
|
196 / 197 / 120
Регистрация: 27.05.2011
Сообщений: 545
|
|
29.08.2015, 19:41 | 7 |
a >>= b тоже самое, что и a = a >> b, только a вычисляется один раз.
Аналогично более популярное a += b.
1
|
1375 / 519 / 72
Регистрация: 21.07.2015
Сообщений: 1,304
|
|
29.08.2015, 19:48 | 8 |
Сообщение было отмечено Alexey104 как решение
Решение
Двоичный сдвиг вправо с присвоением. x >>= n практически эквивалентно x = x / pow(2, n), если предположить, что pow возвращает целые числа (библиотечный возвращает вещественные).
Добавлено через 42 секунды для x =>> 1 <=> x /= 2; Добавлено через 53 секунды Суть всего алгоритма : в первом цикле я ищу первый единичный бит слева, а во втором последовательно вывожу биты слева направо.
0
|
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|
29.08.2015, 19:55 [ТС] | 9 |
Всем спасибо за участие!
Буду разбираться с ">>="...
0
|
29.08.2015, 20:03 | 10 |
Alexey104, да, Дейтелы мне понравились. Для новичков достаточно полно описывают, но это не первая моя книга по Си++, поэтому в крайне редких случаях может быть иногда недостаточно понятно для человека, читающего впервые.
Добавлено через 3 минуты Эта операция просто сдвигает число (его двоичное представление) на n бит вправо. Например 10101001>>1 равно 01010100 (последний бит стерся, грубо говоря, а первый стал нулем, хотя это и не всегда так бывает (посмотрите в интернете про арифметический и логический сдвиг))
0
|
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|
29.08.2015, 21:16 [ТС] | 12 |
shmkv, Ещё раз спасибо, всё понятно.
0
|
29.08.2015, 23:37 | 13 |
Это монадический оператор bind http://hackage.haskell.org/pac... 2--62--61- , разобраться с ним действительно полезно
А если серьезно - то на вопрос ТС нормального ответа так и не было. Но в этом разделе форума квалифицированные участники часто ленятся расписывать правильные ответы, могу предложить только мой недавний пример, приведенный для забаненного ныне участника - Объясните работу рекурсивной функции из книги Г. Шилдта
1
|
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|||||||||||
30.08.2015, 03:14 [ТС] | 15 | ||||||||||
_Ivana, Спасибо, интересно было почитать.
В принципе, я уже сам дошёл до ответа в ходе экспериментов. Написал две функции для отображения первых x чисел ряда Фибоначчи - первую, с использованием рекурсии, вторую - с использованием цикла: рекурсия:
Запустил второй вариант с х = 50 - результат был выведен на экран мгновенно после нажатия клавиши "Enter".
0
|
30.08.2015, 03:27 | 16 |
Подозреваю, что вы только начали свой путь
Хорошо, наивную экспоненциальную рекурсию вы пощупали. Теперь можно попробовать реализовать тех же Фибоначчей также рекурсивными функциями, но 1) экспоненциально с мемоизацией 2) линейно рекурсивно 3) линейно хвосторекурсивно - с аккумулятором. И замерить время, сравнить с вариантом с циклом. Последний вариант можно даже посмотреть ассемблерный скомпилированный листинг и также сравнить с циклом.
0
|
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|
30.08.2015, 03:37 [ТС] | 17 |
Это верно.
Звучит устрашающе. Я так понял, с выводами поспешил, ещё учиться и учиться...
0
|
30.08.2015, 03:40 | 18 | |||||
А вот это правильный вывод Можете посмотреть мои рекомендации в теме по ссылке. А пока вам для развлечения ваша же экспоненциально рекурсивная функция но с мемоизацией - пункт 1 по моему списку.
0
|
4 / 4 / 0
Регистрация: 26.10.2014
Сообщений: 105
|
|
30.08.2015, 19:44 [ТС] | 19 |
Большое спасибо, завтра буду штудировать, а сейчас не мешало бы всхрапнуть, а то башка уже совсем ничего не соображает...
Добавлено через 15 часов 19 минут _Ivana, Ваш алгоритм мне понятен, и, в отличие от моего, он считает молниеносно. Откуда такая разница в быстродействии, я так и не понял, но полагаю, для ответа на этот вопрос нужно изучить ваш список. Буду гуглить, если будут вопросы, задам здесь... Добавлено через 28 минут Всё-таки дошло: Мы же не высчитываем при каждом рекурсивном вызове уже вычисленные при предыдущих вызовах значения! Яков умный...)
0
|
30.08.2015, 21:57 | 20 | |||||
Сообщение было отмечено Alexey104 как решение
Решение
Alexey104, правильно говоришь, Дядя Федор Называется мемоизация (или в простонародии динамическое программирование). Мощная технология, т.к. позволяет быстро считать и такие рекурсивные функции, которые в циклы развернуть не так тривиально, как Фибоначчей.
А дальше я бы все-таки посоветовал вам почитать SICP - хотя бы начало, про итеративные и рекурсивные алгоритмы. Любую рекурсию можно реализовать через циклы - только придется вручную формировать стеки параметров вызовов (что при рекурсии компилятор сделает сам) - про это можно почитать у Кнута. Любые циклы можно реализовать через рекурсию - и для этого вообще не придется ничего костылить. Например, ваш вышеприведенный код циклического вычисления Фибоначчей с последующем же циклическим их выводом на печать - можете попробовать это сделать - это не сложно, но забавно. Если будет сложно - покажу как. Для понимания этого достаточно попрограммировать на любом функциональном языке - в некоторых языках вообще циклов нет как таковых Причем, циклический итеративный алгоритм можно реализовать через частный случай рекурсии - т.н. "хвостовую". Самое забавное, что оптимизирующий компилятор сгенерирует для этого кода точно такой же ассемблерный набор команд, что и для цикла. И здесь мы возвращаемся к SICP - неважно в какой форме реализован алгоритм - в рекурсивной или в итеративно-циклической, главное какая у него структура - итеративная или рекурсивная. Добавлено через 1 час 8 минут ЗЫ ладно, вот ваш второй кот, переписанный через рекурсию:
1
|
30.08.2015, 21:57 | |
30.08.2015, 21:57 | |
Помогаю со студенческими работами здесь
20
С точки зрения закона C точки зрения професcионала. Меню с точки зрения юзабилити БП с точки зрения потребления энергии Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |