Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
1

Целесообразность использования цикла.

18.10.2011, 01:43. Показов 2505. Ответов 22
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Этот момент в универе нам не объясняли. Хочу сразу сказать, я знаю зачем, как и когда используются циклы. Собственно возник не большой спор. Какое преимущество будет иметь код
C++
1
2
for (int i = 0; i < 10; ++i)
    <действие>
перед просто десятью строками типа
C++
1
2
3
4
<действие>
<действие>
<действие>
<действие>
?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.10.2011, 01:43
Ответы с готовыми решениями:

Отсортированные по порядку случайно выбранные номера (целесообразность использования random_shuffle в задании)
Задание звучит так: Карточка лотереи имеет нумерованные поля, из которых случайным образом...

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

Обнуление динамического массива без использования цикла
Как обнулить дин. массив? (без цикла). Для определённого массива можно написать вот так: int array...

Вывод массива без использования цикла на C(pure))
Какие есть мысли и/или готовые решения по сабжу ?

22
33 / 27 / 2
Регистрация: 08.09.2010
Сообщений: 402
18.10.2011, 03:59 2
1) сокращается текст программы
2) в больших программах i может быть больше чем 10, к примеру 100, и тогда будет уже затруднительно писать 100 раз одно и тоже (просто надоест)
0
1 / 1 / 0
Регистрация: 30.06.2010
Сообщений: 19
18.10.2011, 04:19 3
Цикл можно расписать как
C++
1
2
3
4
int i=0;
if(++i<10)<действие>
if(++i<10)<действие>//и так 10 раз
...
По сути получаем еще десять сравнений, и плюс объявление и присваивание значения переменной i
0
Заблокирован
18.10.2011, 08:30 4
ZaxarPal, однозначно, что первый вариант даёт бонус на этапе написания исходного кода.

А дальше нужно смотреть во что скомпилируются оба варианта.

Вполне возможно, что первый вариант после компиляции примет такой же вид, как и второй.
Тогда можно будит сказать, что второй вариант не даёт никаких бонусов.
0
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
18.10.2011, 08:59  [ТС] 5
Вопрос в том, будет ли преимущество по использованию ресурсов системы программой с циклом перед программой без. Т.е. меньше операций процессора, меньше использования оперативки и т.д.
0
Заблокирован
18.10.2011, 09:10 6
Цитата Сообщение от ZaxarPal Посмотреть сообщение
Вопрос в том, будет ли преимущество по использованию ресурсов системы программой с циклом перед программой без. Т.е. меньше операций процессора, меньше использования оперативки и т.д.
Цитата Сообщение от Bers Посмотреть сообщение
А дальше нужно смотреть во что скомпилируются оба варианта.
Вполне возможно, что первый вариант после компиляции примет такой же вид, как и второй.
Тогда можно будит сказать, что второй вариант не даёт никаких бонусов.
Ещё раз вам говорю, зависит от компилятора с его настройками.
После его оптимизаций, вполне возможно что конечный код вообще изменится до неузнаваемости.
1
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
18.10.2011, 10:51 7
Оптимизирующие компиляторы умеют разворачивать даже "длинные" циклы. В данном случае важно, какие операции выполняются в блоке <действие>. Т.е. если там очень сложные вычисления, то экономия одного if на итерацию ничего не даст. Если же сложность действия сопоставима со сложностью условия, то компилятор может принять решение о необходимости развернуть цикл.
В большинстве случаев лапша быстрее цикла. Во многих случаях это преимущество несущественно.
1
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
18.10.2011, 10:59 8
Цитата Сообщение от ZaxarPal Посмотреть сообщение
Этот момент в универе нам не объясняли. Хочу сразу сказать, я знаю зачем, как и когда используются циклы. Собственно возник не большой спор. Какое преимущество будет иметь код
C++
1
2
for (int i = 0; i < 10; ++i)
    <действие>
перед просто десятью строками типа
C++
1
2
3
4
<действие>
<действие>
<действие>
<действие>
?
1. Цикл компактнее в исходинке. А что компактнее в исходнике, то быстрее пишется и читается.
2. Цикл компактнее в коде. А что компактнее в коде, то может быстрее исполняться.
3. В цикле можно быстро поменять число повторов, в том числе, с клавиатуры, или по результатам других операций.
Но циклы не всегда целесообразны. Иногда приходится вручную повторять текст тела цикла вместо написания самого цикла и именно ради быстрого исполнения.
0
Deviaphan
18.10.2011, 11:07
  #9

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
А что компактнее в коде, то может быстрее исполняться.
Оптимизированные по скорости программы обычно больше оптимизированных по размеру.

1
Эксперт С++
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
18.10.2011, 11:10 10
ZaxarPal, смотря для чего это вам. Например, при программной реализации симметричных шифров стараются избегать циклы раундовых преобразований. Вместо for(...) a[i] так и пишут a[0], a[1]... Снимется зависимость от оптимизации компилятора и код работает быстрее.
0
58 / 58 / 6
Регистрация: 10.07.2011
Сообщений: 229
18.10.2011, 11:17 11
Цитата Сообщение от taras atavin Посмотреть сообщение
2. Цикл компактнее в коде. А что компактнее в коде, то может быстрее исполняться.
Уверенности нет. Ключевое слово может.
Приходилось заменять цикл строками для экономии времени исполнения.
0
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
18.10.2011, 11:39 12
Цитата Сообщение от Mustik Посмотреть сообщение
Уверенности нет. Ключевое слово может.
Приходилось заменять цикл строками для экономии времени исполнения.
А что же это такое вы пишете, что циклы вас по времени не устраивают?
Насколько я знаю, циклы реализовываются примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int main()
{
    int arr[] = { 1, 2, 3 };
    
    int i = 0;
begin:
    std::cout << arr[i] << ' ';
    ++i;
    if ( i < 3 )
        goto begin;
}
Т.е. в худшем случае будет проверяться одно условие. Этот цикл просто для примера взял, потому что любой вменяемый компилятор превратит его в 3 строчки вывода.
Приведите пример, при котором будет хоть как-то чувствоваться улучшение быстродействия, если цикл заменить на последовательность действий. Может, такой и существует, самому интересно.
И это уже не говоря о том, что далеко не всегда можно заменить цикл(рекурсия не в счет, она еще менее эффективна).
1
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
18.10.2011, 11:41 13
Цитата Сообщение от diagon Посмотреть сообщение
(рекурсия не в счет, она еще менее эффективна
Это смотря с какой стороны посмотреть, знаете ли
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
18.10.2011, 11:51 14
Цитата Сообщение от diagon Посмотреть сообщение
Т.е. в худшем случае будет проверяться одно условие
Тут суть не в уменьшении на один иф с каждой итерации, а в том, что устраняется ветвление, то есть предиктор на 100% не ошибается, не требуется очистка и перезаполнение конвеера и т.д. Кроме того, если итерации не зависимы между собой, то благодаря всё тому же конвееру, операции могут выполняться "одновременно".
Если в цикле сложное условие, то предиктор может часто ошибаться и производительность никакущая будет.
Последовательный код всегда быстрее кода с ветвлениями, без вариантов.

Цитата Сообщение от diagon Посмотреть сообщение
екурсия не в счет, она еще менее эффективна
Рекурсивные функции могут "инлайница" образуя последовательный код, более эффективный, чем цикл. Ну и разговоры о взаимозаменяемости циклов и рекурсии это просто теоретическое балаболство.)
1
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
18.10.2011, 12:04 15
Цитата Сообщение от fasked Посмотреть сообщение
Это смотря с какой стороны посмотреть, знаете ли
Для каких-нибудь алгоритмов да, но здесь же речь идет о элементарном цикле, а один jmp явно эффективнее вызова функции будет.


Цитата Сообщение от Deviaphan Посмотреть сообщение
Тут суть не в уменьшении на один иф с каждой итерации, а в том, что устраняется ветвление, то есть предиктор на 100% не ошибается, не требуется очистка и перезаполнение конвеера и т.д. Кроме того, если итерации не зависимы между собой, то благодаря всё тому же конвееру, операции могут выполняться "одновременно".
Если в цикле сложное условие, то предиктор может часто ошибаться и производительность никакущая будет.
Последовательный код всегда быстрее кода с ветвлениями, без вариантов.
Я видимо чего-то не понимаю, но, насколько я понял, речь шла о элементарном цикле, который выполняет n(причем n - const) действий. Не могу представить другой задачи, в которой цикл можно заменить на последовательность действий.
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
18.10.2011, 12:17 16
Цитата Сообщение от diagon Посмотреть сообщение
речь шла о элементарном цикле
Я вот не вижу ничего элементарного в записи <действие> .)
Выполняется 10 итераций с выполнением неизвестного объёма кода. Так что тут вообще говорить не о чем, только пространные предположения.)

Допустим, речь о инициализации массива из 10 элементов. цикл удобнее, но последовательное присваивание эффективнее. В относительных величинах - намного эффективнее. В абсолютных - несколько тактов процессора.

Добавлено через 2 минуты
Цитата Сообщение от diagon Посмотреть сообщение
Не могу представить другой задачи, в которой цикл можно заменить на последовательность действий.
Любой цикл с известным количеством итераций (известными до запуска цикла) можно развернуть.
1
Higher
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
18.10.2011, 12:34 17
Цитата Сообщение от Deviaphan Посмотреть сообщение
Допустим, речь о инициализации массива из 10 элементов. цикл удобнее
Здесь удобнее плоский стиль(видел такой термин где-то ) будет =)
C++
1
std::fill(arr, arr + 3, 0);

Цитата Сообщение от Deviaphan Посмотреть сообщение
но последовательное присваивание эффективнее
Чем? Вы же сами сказали
Цитата Сообщение от Deviaphan Посмотреть сообщение
Любой цикл с известным количеством итераций (известными до запуска цикла) можно развернуть.
Компилятор должен развернуть такой цикл, и в бинарном коде особой разницы быть не должно.
1
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
18.10.2011, 12:39 18
Цитата Сообщение от diagon Посмотреть сообщение
Компилятор должен развернуть такой цикл, и в бинарном коде особой разницы быть не должно.
Я как-то упустил из виду это утверждение.) Тогда да, никакой. Но только нужен хороший оптимизирующий компилятор.)

Добавлено через 1 минуту
С другой стороны, пока не залезешь в ассемблерный листинг не поймёшь, развернул он цикл или нет.
С ещё более другой стороны, если он цикл не развернул, то, вероятно, такой потребности не возникло.)
1
Заблокирован
18.10.2011, 12:46 19
Цитата Сообщение от Deviaphan Посмотреть сообщение
Допустим, речь о инициализации массива из 10 элементов. цикл удобнее, но последовательное присваивание эффективнее. В относительных величинах - намного эффективнее. В абсолютных - несколько тактов процессора.
Речь не о работе скомпилированного кода. Речь об оптимизации исходного кода самим человеком.

Если от "разворачивания" цикла будит ощутимый профит, неужели компилятор сам не догадается это сделать?


Одно дело оптимизировать принцип хранения данных (дата-ориентированное программирование)
Другое дело оптимизировать алгоритмы в узких местах.

И третье - пытаться ручками оптимизировать исходный код.

Можно сделать так:

int a=10; int b=a; int c=b; //типа в три действия

можно сделать так:

int a=10; int c=a; //типа в два действия

Но будит наивным полагать, что исходник с тремя действиями будит выполняться дольше. Скорее всего компилятор выбросит промежуточную переменную.

А может и все три переменные выбросит, если они так больше нигде и не будут использованы.
1
1 / 1 / 0
Регистрация: 18.01.2011
Сообщений: 83
18.10.2011, 13:38  [ТС] 20
Вопрос был больше таки в том, как будет работать скомпилированная программа. Большинство непонятных мне моментов Deviaphan разъяснил. Спасибо.
0
18.10.2011, 13:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.10.2011, 13:38
Помогаю со студенческими работами здесь

Как обойти массив без использования цикла
С помощью рекурсии

Ознакомиться с операторами цикла их видами и правилами их использования
Ознакомиться с операторами цикла их видами и правилами их использования....

Опишите сходство и различие использования операторов цикла for, while
0пишите сходство и различие использования операторов цикла for, while и do ... while. Приведите...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru