Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > как работают циклы в java


Автор: juvf 6.11.2013, 05:38
Пример кода
Код

for(int i=0; i<myClass.getSize(); i++)
{
//какой-то полезный код
}


Правильно ли так делать циклы в жаве? Смущает то, что если MyClass::getSize() вернёт 100000, то вызов функции culcSize() будет выполнен 100000 раз. Если тело функции из одной строчки и она не инлайновая, 
Код

MyClass::getSize()
{
return size;
}

то как минимум будет выполнено 100000 входов в функцию getSize() и 100000 выходов. А если гэтСайз - это целый код по вычислению размера, то ещё и этот код будет выполнятся 100000 раз.
Было бы правельнее сделать так
Код

int size = myClass.getSize();
for(int i=0; i<size; i++)
{
//какой-то полезный код
}

Я тонкастями жавы не владею..... Может компилятор жавы сам сделать из 1-го варианта 2-ой и не будет 100000 вызовов?

Автор: андрeй 6.11.2013, 08:22
Цитата

Я тонкастями жавы не владею..... 

Я тоже,
Цитата

... Может компилятор жавы сам сделать из 1-го варианта 2-ой и не будет 100000 вызовов?

Зачем возлагать на компилятор то, что должен делать программист?  
Второй образец кода неверный, примеры правильного кода можно посмотреть в папке с jdk из  файла src.zip

Автор: juvf 6.11.2013, 09:24
Код

Второй образец кода неверный, примеры правильного кода можно посмотреть в папке с jdk из  файла src.zip
 А что не верно? Может синтаксис жавы неверен.... я писал c++_like. Если не сложно, дайте в форум правильную версию кода? 

ps хотя на этом же http://forum.vingrad.ru/forum/topic-77027.html
Код

int cntchars = from + ran.nextInt(to - from+1);
    
    for (int i = 0; i < cntchars; i++) {
//какойто полезный код
    }

Чем мой второй пример кода отличается от этого? 

Автор: андрeй 6.11.2013, 11:12
Цитата(juvf @ 6.11.2013,  09:24)
Код

Второй образец кода неверный, примеры правильного кода можно посмотреть в папке с jdk из  файла src.zip
 А что не верно? Может синтаксис жавы неверен.... я писал c++_like. Если не сложно, дайте в форум правильную версию кода? 

ps хотя на этом же http://forum.vingrad.ru/forum/topic-77027.html
Код

int cntchars = from + ran.nextInt(to - from+1);
    
    for (int i = 0; i < cntchars; i++) {
//какойто полезный код
    }

Чем мой второй пример кода отличается от этого?

Код

MyClass::getSize()
{
return size;
}

Так не сделаешь. Как правильно смотри в пособиях, учебниках и т.п.

Автор: Mirkes 6.11.2013, 12:08
Все зависит от того, что может быть в цикле.
Например, если размер MyClass может изменяться в цикле, то корректным будет только вариант
Код

for(int i=0; i<myClass.getSize(); i++)
{
//какой-то полезный код
}

А вот если Вы ТОЧНО ЗНАЕТЕ, что размер меняться не будет, то можно использовать такой вариант
Код

for(int i=0, n=myClass.getSize(); i<n; i++)
{
//какой-то полезный код
}

 Компилятор не способен решить какой из вариантов выбрать, так что решать придется Вам  smile 

Автор: juvf 6.11.2013, 12:33
2Mirkes
конечно если getSize() в течении цыкла меняет возвращяемое значение - тут вероятнее ошибка программирования. речь не об этом.

допустим вы знаете что возвращяемое значение ТОЧНО не изменится. getSize - это обычный геттер

Код

int MyClass::getSize()
{
return size;
}


size равен 100000. на первый взгляд здесь, по крайней мере в с++, видно сто тысяч входов в функцию getSize, и 100 тысяч выходов. Это же на лицо перегрузка процессора ненужными пустыми операциями.  Допустим вход в функцию 16 тактов, выход - ещё 16. как минимум 3 200 000 тактов теряется в таком коде.  А  getSize возвращяет 1 000 000 000 и потоков 100,  И каждый поток выполняет вычисления....
А если getSize не геттер... а он подсчитывает размер таблицы/людей/машин/молекул/чеготоЕщё, или запрашивает кол-во у какойнить базы данных.... да ещё по TCP.... 

Поспрашивал "живых" жава-программистов - автор ответил что так все пишут, другие толком ни чего не могут сказать. Даже если это простой геттер, не знают - будет ли 100000 входов в функцию getSize(). Меня удивило, что они об этом даже не задумываются. Пишут, потому что так все пишут. Интересно, как жава работает.

Автор: LSD 6.11.2013, 13:04
Цитата(juvf @  6.11.2013,  06:38 Найти цитируемый пост)
Может компилятор жавы сам сделать из 1-го варианта 2-ой и не будет 100000 вызовов?

Первый и второй вариант не эквивалентны. Поэтому компилятор этого делать не будет.

Добавлено через 1 минуту и 16 секунд
Цитата(juvf @  6.11.2013,  13:33 Найти цитируемый пост)
допустим вы знаете что возвращяемое значение ТОЧНО не изменится. getSize - это обычный геттер

Если "вы" точно знаете, то и проведите соответсвующую оптимизацию. Компилятору неоткуда взять эту информацию.

Автор: baldina 6.11.2013, 13:32
juvf,
цикл в форме 
Код

for (type x: container) 
в общем случае эффективней чем
Код

for (int i=0; i < container.size(); ++i)

как раз вынесением вычисления size() из цикла
но вообще java компилятор оптимизирует. как именно, зависит от компилятора.
то, чем вы озабочены, называется преждевременной оптимизацией. делайте код более простым и понятным, оставьте остальное компилятору до того времени, пока производительность достаточна

Автор: Mirkes 6.11.2013, 15:31
Цитата(juvf @  6.11.2013,  12:33 Найти цитируемый пост)
2Mirkes
конечно если getSize() в течении цыкла меняет возвращяемое значение - тут вероятнее ошибка программирования. речь не об этом.

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

Автор: LSD 6.11.2013, 15:37
baldina 
Первый работает через итератор, а итератор это те же самые 2 вызова метода на каждую итерацию. Вместо size()/get() будет hasNext()/next().

Автор: Farmazon 12.11.2013, 03:53
уфф... Если логика метода getSize не очень сложная, то скорее пофигу с точки зрения производительности. В жабе просадку большУю даёт создание объектов и последующая сборка мусора(особенно внезапная, когда не надо), к примеру...
Если логика getSize хитрая(особенно если объекты порождаются), то таки да, будет просадка.

Канонично класс унаследовать от какой-либо реализации(?) Collection и итерировать по ней (или просто одно из полей сделать коллекцией объектов и дать доступ к ней через геттер - это тоже самое, только через композицию)...

Понятнее было бы из контекста задачи, возможно тебе совсем не стоит самому свой контейнер с 0 избретать... Обычно используют готовые коллекции, под конкретные задачи.

А оптимизатор жабы достаточно хитрожоп) http://www.ibm.com/developerworks/ru/library/j-jtp12214/
Как точно будет код работать, нельзя угадать...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)