![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Entry_N3 |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 446 Регистрация: 8.2.2007 Репутация: нет Всего: нет |
Как оптимальнее - переменная внутри цикла или вне - и почему?
Вариант А.
Вариант Б.
Т.е. вариант А или Б? Почему? Другие критерии? |
||||
|
|||||
| SaSho |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 10.6.2007 Где: Днепропетровск Репутация: 2 Всего: 3 |
Насколько я понимаю, если нет надобности работать с объектом вне цикла, то оптимальнее использовать ссылку внутри цикла, дабы не держать лишнюю ссылку на последний объект массива...
P.S. А чем в приведенном выше примере не подходит вариант for-each? Или индекс i используется где-то ещё, кроме как для доступа к элементу массива? |
|||
|
||||
| Entry_N3 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 446 Регистрация: 8.2.2007 Репутация: нет Всего: нет |
SaSho, твое мнение понял. Насчет for-each - речь не конкретно о массиве, а о переменных, которые как-то используются каждую итерацию цикла; вопрос в том, где их лучше объявлять.
|
|||
|
||||
| SaSho |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 54 Регистрация: 10.6.2007 Где: Днепропетровск Репутация: 2 Всего: 3 |
Блох в своём нетленном труде также рекомендует область видимости локальных переменных сводить к минимуму.
|
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
||||
|
||||
| dorogoyIV |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
||||
|
||||
| ivg |
|
||||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Чтобы не быть голословным предлагаю сравнить байт-код двух методов:
|
||||
|
|||||
| maxim1000 |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 3334 Регистрация: 11.1.2003 Где: Киев Репутация: нет Всего: 110 |
ИМХО, всё-таки разница не только для компилятора: переменная должна быть видна там, где предполагается её использование если оно шире, после цикла станет видно на одну переменную больше, причём по задумке она там использоваться не должна, т.е. будет бесполезна вот и получим, что ненужная сущность будет занимать место в "кеше" памяти программиста, отвлекая его от нужных вещей а при программировании сложных систем, количество объектов, которые нужно держать в "кеше" критично
а вот это уже опасно: если переменная не предполагалась для использования вне итерации цикла, программист мог не позаботиться о корректности данных внутри неё и связанных с ней, так что значительно лучше, если программисту придётся вручную вытащить её наружу и при этом посмотреть, какие эффекты это вызовет -------------------- qqq |
||||
|
|||||
| dorogoyIV |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
maxim1000, это все понятно.
конечно надо смотреть на логику самой проги. по кусочку метода трудно что то сказать. поэтому, Entry_N3, на ваше усмотрение... |
|||
|
||||
| Entry_N3 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 446 Регистрация: 8.2.2007 Репутация: нет Всего: нет |
Спасибо за столь широкий взгляд. Лично я думал, что с точки зрения памяти, лучше вне цикла, чтобы не инстанцировать новый объект каждый раз при итерации по циклу, а оказалось, что, наоборот, после цикла переменная остается в памяти.
|
|||
|
||||
| dorogoyIV |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
кажется здесь ты ошибаешься - в цикле каждая переменная будет вешаться в память. только джававский gc будет их удалять. ну и ты можешь вызывать gc если нужно... |
|||
|
||||
| Entry_N3 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 446 Регистрация: 8.2.2007 Репутация: нет Всего: нет |
dorogoyIV, ну так как лучше с точки зрения памяти - вне цикла или внутри?
|
|||
|
||||
| niasilil |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 325 Регистрация: 4.6.2007 Где: USA Репутация: 8 Всего: 9 |
кстати, сколько байт в памяти занимает одна reference? чего то нигде не встречал.
Это все ловля блох, примерно как табу на использование String внутри цикла - все говорят что "нельзя и все, надо StringBuilder/StringBUffer". При том что если цикл в 10 шагов, то GC все равно соберет эти String объекты и освободит память. -------------------- SCJP 5.0, SCJD |
|||
|
||||
| ivg |
|
||||||||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Если вы имеете ввиду, что для локальной переменной объявленной внутри цикла, при каждом проходе, будет выделяться новая ячейка памяти, то это не так. Будет использована старая. Вот тут - VM Spec: 3.6 Frames, можно посмотреть. И GC не управляет фрэймами локальных переменных, фрэйм создаётся/уничтожается при входе/выходе в/из метода. Внутри. После выхода за пределы блока, ячейка фрэйма может быть переиспользована компилятором для хранения другой локальной переменной. Следовательно меньше размер фрэйма локальных переменных, выделяемых методу. Почему табу? На это есть объективные причины. Например такой код:
|
||||||||
|
|||||||||
| Entry_N3 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 446 Регистрация: 8.2.2007 Репутация: нет Всего: нет |
ivg, круто
|
|||
|
||||
| dorogoyIV |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
ну так переменная вне цикла |
|||
|
||||
| dorogoyIV |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1503 Регистрация: 26.3.2007 Репутация: 3 Всего: 46 |
если инициализируешь какой то объект, то внутри (зачем лишние объекты)
в работе программы все равно потребуется какое то возвращаемое значение
|
||||
|
|||||
| cube |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 11.4.2007 Репутация: 2 Всего: 3 |
Что вы имеете ввиду под словом "оптимальнее", производительность? Или что?
Если производительность, то объявляйте переменную вне цикла, проведите тест и ты убедитесь, что работаьт так будет быстрее, я еще не читал ссылку которую вы скинули, но по старой памяти знаю, что в ява машине память для переменной каждый раз будет выделяться заново при каждой итерации! Выделение новой памяти задача более ресурсоемкая, чем перезапись значения в уже однажды выделенной памяти. Если же верить тому, что говорите вы, тогда как объяснить смысл переменных? Вы хотите сказать, что каждый раз при новой итерации выделение новой памяти происходить не будет и тогда ссылка будет на один и тот же объект?! (когда переменная используется внутри цикла) |
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Вы ссылку на объект с самим объектом не путаете? Ясно понимаете чем они отличаются? Локальная переменная - суть место для её значения во фрейме метода. Локальная объектная переменная - суть место для значения ссылки на объект во фрейме метода. Если в это место будет записано новое значение ссылки, объектная локальная переменная станет ссылаться на другой объект. |
|||
|
||||
| cube |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 11.4.2007 Репутация: 2 Всего: 3 |
Я ничего не путаю) Мне это интересно На какой объект ссылаться? Т.е. в данном примере освобождение и выделение памяти при каждой итерации цикла происходить не будет?
Это сообщение отредактировал(а) cube - 1.9.2008, 14:08 |
|||
|
||||
| ivg |
|
|||
![]() Autonomous R&D ![]() ![]() Профиль Группа: Участник Сообщений: 686 Регистрация: 8.2.2006 Где: Екатеринбург Репутация: 33 Всего: 81 |
Аааа, вот вы о чём....
Посмотрите внимательно первый пост и название темы, там нет никакой речи о new..... Не думаете же вы, что объектная локальная переменная, может быть получена только с помощью new....? |
|||
|
||||
| cube |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 291 Регистрация: 11.4.2007 Репутация: 2 Всего: 3 |
извините, я просто неправ, там везде были ссылки |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |