Форум программистов, компьютерный форум, киберфорум
Священные войны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.50/26: Рейтинг темы: голосов - 26, средняя оценка - 4.50
 Аватар для Buckstabue
179 / 127 / 25
Регистрация: 12.01.2012
Сообщений: 623

Насколько критично обьявление переменной в теле цикла?

28.08.2012, 17:23. Показов 6152. Ответов 66

Студворк — интернет-сервис помощи студентам
Часто приходится иметь дело с циклами в которых используются некоторые специфичные вспомагательные перменные, которые нужны только внутри цикла. Вопрос: как сказывается объявление переменных внутри тела цикла на производительность?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.08.2012, 17:23
Ответы с готовыми решениями:

[C++] объявление переменных в теле цикла
pilot007, во-первых ни когда не объявляй переменные в теле цикла. Во-вторых заголовки циклов наработками по выбору кратчайшего пути не...

В теле цикла for, переменной не присваивается значение
Суть программы в том, чтобы перевести число из десятичной системы в двоичную. Переменные: bin = бинарное число(результат) dec =...

Доступ к переменной, объявленной в теле цикла
Здравствуйте, есть следующий код using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

66
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
31.08.2012, 15:02
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Угу, по int i; в начале функции я могу сделать очень важный вывод, что в функции, возможно, где-то есть цикл. А то и несколько.
по int i; в начале блока ты можешь сделать вывод, какое имя занято, а какие - свободны
в C точно так же принято объявлять переменные локально в блоке
но когда у тебя несколько циклов, ты действительно можешь в каждом из них использовать одну и ту же переменную
мало того, такая переменная ещё и сохраняет своё значение после цикла, которое ты тоже можешь использовать

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

если же у тебя вдруг переменные в начале блока перестали связываться с кодом, то есть ты уже не "видишь", что к чему относится, то нужно подумать о разделении кода
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
31.08.2012, 21:24
Просто не надо писать мегамонстров с тысячами имён и на сотни строк. Когда имён мало, коллизии редко происходят. А когда строчек мало, искать особо не приходится.

Меня в объявлении переменных в начале функции больше раздражает то, что если меня переклинит и понадобится переменная вот прям с этого места, то надо идти куда-то в начало функции и объявлять её там. Если поменять тип — тоже.

А ещё отдельной строкой раздражает отрыв типа переменной от её инициализации. Вот есть функция:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void func()
{
  // объявили
  typename LongNamespace<Several, Template, Parameters>::kindaLongTypeName veryLongAndDefiniteVariableName;
  /*
    десяток
    строк
    кода
    для
    вычисления
    необходимого
    значения
    переменной
    veryLongAndDefiniteVariableName
  */
  veryLongAndDefiniteVariableName = otherVariable * 2;
}
И тут меня переклинивает, что я написал не тот тип у переменной.

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

А ещё я не хочу писать этот долбаный тип полностью, я хочу написать auto и пусть мне конпелятор выведет тип. Но нет, этого я сделать не могу, потому что нельзя вычислить значение-инициализатор в самом начале, а объявить переменную на месте не позволяет религия.

И не надо про "продумывать код и необходимые переменные заранее" и "IntelliSense всё покажет в попапе". Если программу можно легко читать только с IDE, это явно что-то с программой и её стилем.

Я уж молчу про то, что (омг! как можно было пропустить эту огромную брешь в производительности) в самом начале вызывает аж один лишний конструктор по умолчанию, а потом ещё один оператор присваивания, вместо только одного конструктора по значению при создании.
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
01.09.2012, 00:21
Кто Вам сказал, что мы читаем в IDE? Я весь чужой код смотрю в Notepad++, и там же чаще пишу, а IDE в основном для сборки, и поправки мелких нюансов. И, поверьте, ничем не затрудняет ни читать ни писать. А вот если Вы не можете посмотреть вверх, чуть выше 20 строк, которые полностью помещаются на современных мониторах, ну... тут я уже даже не знаю что и сказать...

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
в самом начале вызывает аж один лишний конструктор по умолчанию, а потом ещё один оператор присваивания,
Ага, представьте себе, и это вместо сотен вызовов "конструктора по значению" и столько же раз деструктора, вместо сотни раз выделения и освобождения памяти.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
01.09.2012, 03:54
Цитата Сообщение от ForEveR Посмотреть сообщение
Это на Сях нужно объявлять переменные в начале функции
не обязательно в начале функции, можно в начале любого блока (в C90 точно можно) или вообще мешать объявление и код, как в С++ (начиная с С99)
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
01.09.2012, 06:50
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Просто не надо писать мегамонстров с тысячами имён и на сотни строк.
да ты даже с тремя именами уже будешь должен перечитывать код, отыскивая определения
пусть там в среднем двадцать строк, умножь их на сотню функций

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
то надо идти куда-то в начало функции и объявлять её там
зато, когда ты откроешь этот код через несколько месяцев, ты очень быстро в него вникнешь, а если это вообще не твой код, то ты будешь только рад увидеть всё в одном месте, откомментированное

и где вообще гарантия, что человек, создавший переменную в середине действий, будет использовать её только там, где создал ? а переделать код, тоже нужно запоминать там где и что (потому что они все разбросаны по коду)

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
раздражает отрыв типа переменной от её инициализации
я инициализирую либо перед первым действием, либо в специальном месте инициализации

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
А потом я эту переменную использую в первый раз, но позабыл её начальное значение — ага, лезть вверх смотреть
инициализируй прямо там, на месте

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
а объявить переменную на месте не позволяет религия
объявил переменную на месте - потерял её из виду
потерял её из виду - не можешь понять код
не можешь понять код - не знаешь, есть в нём ошибки или нет

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
И не надо про "продумывать код и необходимые переменные заранее"
нет, не заранее, просто предусматриваешь возможность расширения списка переменных
если получается большой, код нужно разделять
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21285 / 8310 / 637
Регистрация: 30.03.2009
Сообщений: 22,671
Записей в блоге: 30
24.09.2012, 14:18
На всякий случай, ссылка на похожее обсуждение
Соптимизирует ли (любой) компилятор такой код?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.09.2012, 08:25
Цитата Сообщение от NoMasters Посмотреть сообщение
Не хранится хлам, у компилятора больше простора для оптимизаций.
Ну и простор для оптимизации при многократном выделении и освобождении памяти.
(-8
Всё равно, что вызов функции с параметрами и локальными переменными вложить в цикл, только там все эти накладные расходы оправданы, а переменные в теле цикла то же самое делают на пустом месте. Если же они статик, то хранятся от первого создания и до закрытия проги.

Добавлено через 3 минуты
Цитата Сообщение от Buckstabue Посмотреть сообщение
И компилятор сгенерировал код так, чтобы не происходило новое выделение памяти, вывод:
0xbff4a524 1
0xbff4a524 2
0xbff4a524 3
0xbff4a524 4
0xbff4a524 5
Этот вывод ничего не доказывает: стек один, дно его зафиксировано и сколько не дёргай в цикле туда-сюда вершину для выделения и освобождения локальной памяти, она будет на одних и тех де адресах.

Добавлено через 4 минуты
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
А вообще советую не экономить на спичках. Сейчас не 80-е годы и компиляторы не тупые. Надо очень хорошо знать ассемблер и архитектуру целевого процессора, чтобы генерировать руками код лучше, чем компилятор.
Многие переменные занимают свыше 90% оперативы одним экземпляром и часто именно они нужны только внутри цикла, а компиляторы на ИИ ещё долго не будут строить.

Добавлено через 6 минут
И однократное создание переменной может занимать до десятков секунд, что повесит цикл даже с жалким миллиардом шагов на десятки, а то и более сотни лет.

Добавлено через 16 минут
А взваливение на компилятор задачи угадывания собственного замысла - это попытка быть глупее его. Не надо воображать, будто компилятор действительно умён и сможет изменить алгоритм больше, чем заменой на гарантированно эквивалентный, или в случае, не ясном хотя бы одному ламеру, а тем более полностью написать прогу за автора. Время существования переменных, как встроенных типов, так и объектов и области видимости идентификаторов оптимизируются только вручную и вообще не автоматизируются, ответственность за всё перечисленное - прерогатива истинного интеллекта и творческой мысли, а не тупой железяки. А если вам жалко памяти на две однотипные переменные, нужные в двух не вложенных циклах одной подпрограммы, то объявите одну и просто меняйте её роль. Можно даже юньон для этого юзать, чтоб у неё было два разных смысловых имени для обеих ролей. Или одно имя - обычный идентификатор, а второе - макрос, объявляющий его синоним для препроцессора.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.09.2012, 08:25

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

Насколько критично использование Linux для обучения Ruby?
Всем привет! Смотрю первый урок от hasBrains по Ruby, там автор сильно рекомендует использование Ubuntu или MacOS для обучения Ruby. ...

Насколько критично в плане безопасности использование SSL при POST запросах?
Добрый день! Для обмена информацией САЙТ &lt;-&gt; 1С используются POST запросы (в обе стороны). Насколько критично использовать...

Ошибок парковок очень много (осталась одна красная по Виктоории), а СМАРТ - гуд. Насколько критично?
Доброе время суток! Виктория 4,47: СМАРТ Ошибок парковок ну очень много, а СМАРТ - гуд Под админом выполнил hdparm, появилось в...

вывод на экран чисел 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12, с использованием одного цикла и что бы все printf были только в теле цикла
вывод на экран чисел 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12, с использованием одного цикла и что бы все printf были только в теле...


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

Или воспользуйтесь поиском по форуму:
67
Ответ Создать тему
Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru