|
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
|
||||||
Где лучше эти переменные объявлять?29.10.2011, 21:03. Показов 5066. Ответов 31
Метки нет (Все метки)
Посмотрите пожалуйста на следующий код (код сишный, но компилировался как C++, так как в чистом Си нет ООП... Но не это меня в данном случае интересует). А интересует следующее. В классе есть 8 функций, в которых в циклах используется переменная i. В данном коде я ее объявил в классе, как приватную, которая одна для всех функций. Но так, как учили делать, говорят, что эта переменная должна быть у каждой функции своя и объявляться типа так: for(int i=0; бла-бла-бла). Но я не пойму одного момента... Ведь получается, что если делать так, как в последнем случае, то за всю работу программы эта переменная i будет десятки раз создаваться, потом удаляться десятки раз при выходе из функции. Разве это оптимально?
0
|
||||||
| 29.10.2011, 21:03 | |
|
Ответы с готовыми решениями:
31
Как лучше объявлять переменные Как и где объявлять глобальные переменные типа String? |
|
8 / 8 / 2
Регистрация: 13.07.2010
Сообщений: 14
|
|
| 29.10.2011, 22:54 | |
|
Оптимально с какой точки зрения? По скорости выделение локальных переменных одинаково, хоть сотня их там будет, т.к. локальные переменные хранятся на стеке и выделяются простым изменением указателя стека.
По памяти оптимально, т.к. когда переменная не нужна она не хранится (так можно для всех процедур выделить память заранее, чтобы потом не выделять, но это шаг назад, к прошлому языков программирования Тут же можно задаться вопросом оптимальности использования ООП перед процедурными парадигмами или вообще принципами ассемблера) Но, думаю, на память таких размеров в наши дни пофиг. Важнее соблюдение парадигмы программирования (влияет на понятность программы, вероятность возникновения и слложность поиска ошибок.) Так что правильно учат: всему свое место, включая переменные.
1
|
|
|
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
|
|||
| 29.10.2011, 22:59 [ТС] | |||
|
0
|
|||
|
Заблокирован
|
||
| 29.10.2011, 23:21 | ||
|
Каждый раз при входе в функцию он будит создаваться, а при выходе - разрушаться. Если класс постоянно его использует внутри своих методов, не лучше ли тогда сделать его один раз в качестве приватных данных-членов? Что бы не пришлось каждый раз запускать конструктор класса, и захватывать ресурсы?
1
|
||
|
213 / 139 / 8
Регистрация: 18.08.2010
Сообщений: 1,018
|
|
| 29.10.2011, 23:26 [ТС] | |
|
Bers, вот-вот
Потому я и решил узнать ответ на этот вопрос на форуме, чтобы в дальнейшем разумно распоряжаться с ресурсами при коддинге.
0
|
|
|
8 / 8 / 2
Регистрация: 13.07.2010
Сообщений: 14
|
|||||||||||||||||||||||
| 30.10.2011, 01:05 | |||||||||||||||||||||||
|
Ну не совсем без разницы. Тут может быть 2 случая:
1) Если в подпрограмме нет локальных переменных, то выполнится на 1 процессорную инструкцию меньше (вычитание числа - размера памяти для локальных переменных из указателя стека) 2) иначе, если есть другие локальные переменные, тогда действительно без разницы, потому что появление еще одной переменной увеличиват вычитаемое число, а не количество инструкций. Честно, пока не встречал, чтобы программы на языках высокого уровня оптимизировали вплоть до учета каждой процессорной команды, это скорее относится к языкам ассемблера. А учат так потому что существуют парадигмы программирования (принципы написания программ на том или ином языке). И обзявление переменных как можно ближе к месту их использования относится к этим требованиям (хотя их вроде и нарушать иногда можно). p.s. По ходу рассуждения над Вашим вопросом возник другой: есть ли разница по скорости между
Добавлено через 1 час 32 минуты Вынужден Вас огорчить: эксперимент с компиляцией различных вариантов объявления переменной ни к чему хорошему не привел:
в release вызов метода явно не представлен: программа скомпилировалась как последовательность команд. Как оно будет выглядеть в более сложных случаях сказать сложно. Отсюда можно сделать выводы: 1) Отнести выделение памяти для переменных к статическому распределению памяти (оно изначально быстрое) и предоставить работу по оптимизации компилятору. 2) Разделить выделение памяти на статическое и динамическое (более медленное). Получается, каждый случай специфичен, и нельзя дать универсальный ответ, как правильно поступить. Будет лучше изучить, как устроена работа с объектами, выделением памяти, хорошо в этом разобраться и руководствоваться здравым сыслом.
0
|
|||||||||||||||||||||||
|
Заблокирован
|
||
| 30.10.2011, 01:20 | ||
|
Если же это примитивный локальный int, то и нечего заморачиваться. Я правильно вас понял?
0
|
||
|
8 / 8 / 2
Регистрация: 13.07.2010
Сообщений: 14
|
||
| 30.10.2011, 11:21 | ||
|
Bers, из ваших слов
Вы бы пример привели какой-нибудь, чтобы можно было о чем-то конкретном спорить. (ну или контр-пример для моих рассуждений, который покажет что я не прав )
0
|
||
|
Заблокирован
|
|||||||
| 30.10.2011, 12:31 | |||||||
|
2. Пример - класс Контейнера2Д. На самом деле это обертка на вектором контейнеров (по умолчанию - над вектором векторов) Предоставляет интерфейс управления "матрицей". Многие методы внутри себя создают Итератор вектора. И с его помощью осуществляют пробег по массиву. Например:
1. Многие методы вынуждены постоянно создавать их, и разрушать. 2. Обертка позволяет хранить строки матрицы не только в виде вектора, но и в виде стринга, виде дека, в виде самопального какого нибудь одномерного контейнера. А это значит, что теоретически, итератор может быть каким угодно, вплоть до того, что будит жрать дин. память. Поэтому, у меня есть крамольные мысли, что есть смысл заранее сделать в классе четыре итератора (два для для самой таблицы, два для строки таблицы). Что бы сократить время на создавание и инициализацию их в каждом методе. Кроме того, по правилу "единого интерфейса", контейнер-таблица окажет себе большую услугу, если максимально будит похож на все прочие контейнеры стл. То бишь, итераторы таблицы неплохо было бы забацать в виде статик-членов... /ps метод не доделан, там нужно с константностью всего метода разобраться
0
|
|||||||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||
| 30.10.2011, 13:13 | ||
0
|
||
|
Заблокирован
|
||
| 30.10.2011, 13:28 | ||
|
Однако записть типа: typename tCont::const_iterator Begin; Мне прозрачно намекает, что итераторы являются: - статиками, - данными-членами класса.
0
|
||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||||||
| 30.10.2011, 13:36 | ||||||
|
Bers, ЭЭЭ... Вы ничего не забыли?
0
|
||||||
|
Заблокирован
|
||
| 30.10.2011, 13:46 | ||
|
А вы покажите реализацию метода std::vector<int>::begin(); Сразу станет понятно, он создается заново каждый раз, или присутствует в принципе. И потом, вопрос все равно остаётся: создавать итератор каждый раз заново в каждом методе, где требуется пробег по вектору. Или сделать его один раз членом-данным, и не тратить время на создание/разрушение ?
0
|
||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||||||
| 30.10.2011, 14:48 | ||||||
|
Bers,
Bers, А по сабжу - создавать когда нужен.
0
|
||||||
|
Заблокирован
|
|||
| 30.10.2011, 14:54 | |||
|
0
|
|||
|
В астрале
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
|
||||||
| 30.10.2011, 14:58 | ||||||
|
Bers, Вот _NextNode - объект, содержащийся в классе. Но итератор создается только когда нужен, при вызове begin к примеру.
Резоннее создавать объекты, тогда и только тогда, когда они нужны. Добавлено через 2 минуты Хотя нет. Я не прав.
0
|
||||||
|
Заблокирован
|
|||
| 30.10.2011, 15:06 | |||
|
Служебные данные-члены выполняют по сути точно такую же задачу, как и пулы. Хотя конечно, в примере с вектором сэкономить на итераторах явно не получится.
0
|
|||
|
Заблокирован
|
||
| 30.10.2011, 19:16 | ||
![]() Теперь что касается вашего вопроса. Ваша переменная i, никакой полезной информации о классе не несет. Вы лишь засоряете объявление своего класса рабочими переменными, которые нужны лишь кратковременно. Но зато вы при этом увеличиваете размер своего класса! И к тому же запутываете пользователей вашего класса! К тому же вы ничего на самомделе не оптимизируете! Еслибыэта переменная была былокальной переменной каждой функции, то компилятор мог бьпоместитьее в один регистр, икодбыл быкомпактным, так как никакие дополнительные машинные инструкции пообращению к этой переменной не требовались! Другое дело, когдаэта переменная - член класса. Теперь к ней можнообратиться лишьчерез указатель this. То естьпоявляютсядополнительные машинные команды по обращению к этой переменной. Так что я усматриваюлишь одни минусы в вашем подходе!
2
|
||
| 30.10.2011, 19:16 | |
|
Помогаю со студенческими работами здесь
20
Глобальные переменные, методы - где лучше заводить?
Как правильно объявлять переменные? Как объявлять глобальные переменные в с#? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение:
В этой книге («Подход, основанный на вариантах использования») Ивар утверждает,
что архитектура программного обеспечения — это
структуры,. . .
|
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога
Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
|
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip
На первой гифке отладочные линии отключены, а на второй включены:. . .
|
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога
Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем.
. . .
|
|
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
|
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
|
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
|
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога
Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
|