LINUX.ORG.RU

Ranged for vs Indexed for

 


1

5

Что в должно быть быстрее на arm для контейнера std::vector<T>?

Ranged for:

std::vector<SomeStruct> vec;
for (const auto& v : vec)
{
  // do something with v
}


Indexed for:
std::vector<SomeStruct> vec;
for (size_t i = 0, size = vec.size(); i < size; i++)
{
  const auto& v = vec[i];
  // do something with v
}


Мои синтетические замеры дают приблизительно одинаковые результаты. Профилирование под xcode показывает странные результаты - indexed for получается иногда сильно быстрее, чем range for.
Самостоятельно выводы сделать не получается, надеюсь на коллективный разум ЛОРа.

★★★★★
Ответ на: комментарий от anonymous

Жаль, что вас не учили не уводить разговор от темы. Как ваш олдскул и for vs while относится к теме топика?

andreyu ★★★★★
() автор топика
Ответ на: комментарий от andreyu

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

i-rinat ★★★★★
()
Ответ на: комментарий от anonymous

«когда есть простая инициализация и инкрементирование переменных цикла» и «когда число итераций заведомо известно» - не одно и то же

for(char*ch = string; *ch; ch++)
MyTrooName ★★★★★
()
Ответ на: комментарий от anonymous

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

MyTrooName ★★★★★
()
Последнее исправление: MyTrooName (всего исправлений: 1)
Ответ на: комментарий от i-rinat

Он сложен только для новичка. Тот, кто пишет цикл, в теле которого меняется размер контейнера, читает такой код легко.

Одним словом, ваша претензия исключительная вкусовщина.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от andreyu

Тот, кто пишет цикл, в теле которого меняется размер контейнера

... поступает неправильно.

Одним словом, ваша претензия исключительная вкусовщина.

Нет. Это неприязнь к трюкачеству.

Думаю, у многих такое бывает: «смотри, как я могу». К сожалению, у некоторых это не проходит. Видимо, они недостаточно уверены в себе, чтобы писать простой для понимания код.

i-rinat ★★★★★
()
Ответ на: комментарий от MyTrooName

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

что это, неудачная попытка проредить массив вдвое?

MyTrooName ★★★★★
()
Ответ на: комментарий от MyTrooName

«когда есть простая инициализация и инкрементирование переменных цикла» и «когда число итераций заведомо известно» - не одно и то же

Фактически, одно и то же :-)

for(char*ch = string; *ch; ch++)

Тут как раз число итераций известно - оно равно strlen(string), поэтому for тут уместен :-) Так что пока мимо :-) Давай ещё пример :-)

anonymous
()
Ответ на: комментарий от MyTrooName

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

Стараться включать голову нужно после того, как учителя тебе объяснят базис :-) K&R - не просто учителя, но и изобретатели C :-) Они мне объяснили основы того, как нужно использовать C :-) А дальше, стараюсь сам :-) Лол :-)

anonymous
()
Ответ на: комментарий от andreyu

Он сложен только для новичка.

Он демонстрирует применение for ни к месту :-) Используй while, тогда и претензий к себе не услышишь :-)

Тот, кто пишет цикл, в теле которого меняется размер контейнера

Тот, обычно, использует while, чтобы не вводить других в заблуждение :-)

anonymous
()
Ответ на: комментарий от MyTrooName

а как написать уникализацию отсортированного массива без изменения границы?

Ты про это?

v.erase(std::unique(v.begin(), v.end()), v.end());

i-rinat ★★★★★
()
Ответ на: комментарий от andreyu

Жаль, что вас не учили не уводить разговор от темы.

Меня учили :-) По теме я уже сказал - вы просто зря теряете время :-) Ваш топик, по сути, называется «итераторы против индексов» :-) Итераторы вектора в цепепе абсолютно ни в чём не уступают индексам :-) Хоть в теории, хоть на практике :-) Так же, как и unique_ptr<Foo> не уступает Foo* :-) Если, конечно, правильно включить все оптимизации :-)

Как ваш олдскул и for vs while относится к теме топика?

Ну это я так, в качестве дополнения :-)

anonymous
()
Ответ на: комментарий от i-rinat

Я не понимаю код ядра линукс, значит ли это что код ядра плохой?

Впрочем я удивлён, что вы умудрились заблудиться в цикле из двух строк.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от anonymous

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

andreyu ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Ваш топик, по сути, называется «итераторы против индексов»

Да вы настоящий КО.

Ваше утверждение «ни в чем не уступают» как минимум глупо.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от andreyu

Ваше утверждение «ни в чем не уступают» как минимум глупо.

Лол :-) Это утверждение было бы глупым, будучи применённым вне контекста :-) Сейчас контекстом является производительность :-) В этом контексте итераторы ни в чём не уступают индексам :-)

anonymous
()
Ответ на: комментарий от andreyu

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

Почему никакой пользы? :-) А вдруг уважаемые читатели будут использовать for и while по назначению? :-) И мне или кому-то ещё потом будет проще сопровождать их писанину? :-) Лол :-)

anonymous
()
Ответ на: комментарий от andreyu

Под сопровождением вы подразумеваете балобольство вне темы?

Лол :-) Под сопровождением я понимаю заказ на доработку какой-нибудь части существующей системы :-) К большой печали, часто такие системы написаны некими ламерками, не знакомыми с олдскулом, а потому приходится пробиваться через тонны известной субстанции, чтобы понять что же происходит на самом деле :-) Однако когда ламеркам начинаешь рассказывать, что они нагенерили тонны навоза, в котором трудно произрасти жемчужину, они начинают обижаться и почему-то считать, что «вот пришёл очередной умник, который считает себя умнее других. сколько таких было и все жаловались на наш код, хотели его переписать» :-) Оно и понятно - мамерки всегда горазды винить кого угодно, кроме себя :-)

anonymous
()
Ответ на: комментарий от andreyu

Ну, кстати, у вас код ничего так :-) Очень даже можно читать без рвотного рефлекса :-) Молодец :-)

anonymous
()
Ответ на: комментарий от anonymous

Ну, кстати, у вас код ничего так :-)

Откуда вы знаете?

Очень даже можно читать без рвотного рефлекса :-) Молодец :-)

Мнение анонима очень ценно ...для того же анонима.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от anonymous

В C for - это for :-) За пруфом читать K&R, глава 3.5 :-) Там же можно обнаружить рекомендации когда следует предпочесть for - когда есть простая инициализация и инкрементирование переменных цикла :-) Т.е. когда число итераций заведомо известно :-)

А можно цитату про «заведомо известно»? Потому что я читал немножко другое:

Выбор между while и fоr определяется соображениями ясности программы. Цикл for более удобен в тех случаях, когда инициализация и приращение шага логически связаны друг с другом общей переменной и выражаются единичными инструкциями, поскольку названный цикл компактнее цикла while, а его управляющие части сосредоточены в одном месте.

Т. е. пример andreyu из этого камента

for (size_t i = 0, size = vec.size(); i < size; i++)
{
  size_t idx = size - i - 1;
  vec[idx] = vec[--size];
  vec.pop_pack();
}

следовало бы в соответствии с рекомендациями K&R переписать так:

for (size_t i = 0, size = vec.size()-1; i <= size; i++, size--)
{
  size_t idx = size - i;
  vec[idx] = vec[size];
  vec.pop_back();
}

Более того, рекомендуя сосредотачивать в одном месте управляющие части цикла for, K&R совсем не настаивают на этом:

Это похоже на DO-циклы в Фортране и for-циклы в Паскале. Сходство, однако, не вполне точное, так как в Си индекс и его предельное значение могут изменяться внутри цикла, и значение индекса i после выхода из цикла всегда определено. Поскольку три компоненты цикла могут быть произвольными выражениями, организация fоr-циклов не ограничивается только случаем арифметической прогрессии. Однако включать в заголовок цикла вычисления, не имеющие отношения к инициализации и инкрементированию, считается плохим стилем. Заголовок лучше оставить только для операций управления циклом.

Что же касается заведомой известности числа итераций, то у K&R масса примеров, в которых условием выхода из цикла for является возврат функции getchar(), т. е. число итераций как раз наоборот заранее неизвестно. Например:

#include <stdio.h>

/* подсчет вводимых символов; 2-я версия */
main()
{
 double nc;
 for (nc = 0; getchar() != EOF; ++nc)
     ;
 printf ("%.0f\n", nc);
}

И это не единственный такой пример.

aureliano15 ★★
()
Ответ на: комментарий от andreyu

Откуда вы знаете?

Вы сами показали :-) Загляните в свой профиль :-) Лол :-)

Мнение анонима очень ценно ...для того же анонима.

Не, ну правда ведь код нормальный :-) Можно с ходу без проблем читать :-) Все бы так писали, хотя бы, было хорошо :-)

anonymous
()
Ответ на: комментарий от aureliano15

А можно цитату про «заведомо известно»?

Можно :-) Но тогда я буду цитировать самого себя :-)

Потому что я читал немножко другое

У K&R нет про «заведомо известно» :-) Считай, что это моя олдскул :-) Так же рекомендую считать это хорошим стилем :-)

Однако включать в заголовок цикла вычисления, не имеющие отношения к инициализации и инкрементированию, считается плохим стилем.

Лол :-) Ну да :-) И, продолжая эту мысль до логического конца, можно утверждать, что включать в тело цикла for вычисления, имеющие отношения к инициализации и инкрементированию, считается плохим стилем :-) Выше ты продемонстрировал свою приверженность этой мысли :-)

K&R масса примеров, в которых условием выхода из цикла for является возврат функции getchar(), т. е. число итераций как раз наоборот заранее неизвестно

Это они зря :-) Вот как надо:

#include <stdio.h>

/* подсчет вводимых символов; 2-я версия */
main()
{
 double nc = 0;
 while (getchar() != EOF) ++nc;
 printf ("%.0f\n", nc);
}

Так короче, понятнее, и nc инициализирована в месте объявления :-) Лол :-)

anonymous
()
Ответ на: комментарий от anonymous

Так короче, понятнее, и nc инициализирована в месте объявления :-) Лол :-)

С этим я полностью согласен. Но всё-таки приписывать K&R собственные мысли, пусть даже правильные, как-то неправильно, имхо. :-)

aureliano15 ★★
()
Ответ на: комментарий от anonymous

Тут как раз число итераций известно - оно равно strlen(string)

кому известно? ванге? strlen(string) может хоть в бесконечный цикл уйти в определенных экзотических условиях, ну или дать segfault

Давай ещё пример :-)

пока с тебя и этого хватило

MyTrooName ★★★★★
()
Ответ на: комментарий от andreyu

Затем, что бывают случаи, когда размер контейнера меняется внутри цикла

Перечитал сей перл трижды, не понял, что происходит. Ревью не пройдено, до свидания.

anonymous
()
Ответ на: комментарий от unanimous

Накой черт вы с этим идиотом общаетесь?

Почему идиотом? В общем мысли о читабельности/нечитабельности кода верные. Лично мне не понравилась неуместная отсылка к Кернигану и Ритчи, т. к. это авторитеты, само упоминание которых для многих может быть железобетонным аргументом. А если этот аргумент фальшивый, то и идеи, которые он доказывает, могут быть скомпрометированы в глазах многих. И вообще я против бездумной апелляции к авторитетам без более основательного обоснования своих (или их) идей. А так, в целом всё правильно человек сказал.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Т. е. пример andreyu из этого камента

Если упереться именно в тот пример, то переписать его можно так:

vec.clear();


Но если в цикле появится условие (а иначе какой смысл копировать элемент в самого себя, а потом его удалять?):
for (size_t i = 0, size = vec.size(); i < size; i++)
{
  size_t idx = size - i - 1;
  if (vec[idx].readyToRemove())
  {
    vec[idx] = vec[--size];
    vec.pop_pack();
  }
}


То ваше «следовало бы в соответствии с рекомендациями K&R переписать так:» становится неверным.

В любом случае, в топике речь о языке C++ от Б. Страуструпа, а не о языке C от Б. Кернигана и Д. Ритчи. И конкретно речь идет о indexed for против ranged for, о чем и сказано в теме топика.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Вы сами показали :-)

Неужели?

Загляните в свой профиль :-)

А как, по вашему, в моем профиле что-то появилось?

andreyu ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Перечитал сей перл трижды, не понял, что происходит.

Значит вас нужно гнать из профессии ссаными тряпками.

Ревью не пройдено, до свидания.

Я к вам на ревью и не приходил.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от MyTrooName

кому известно?

Всем известно, что strlen(string) возвращает количество элементов типа char от string до '\0' :-) Тебе это тоже известно, но ты, почему-то, начинаешь прикидываться :-) Хотя понятно, ведь твоя задача сейчас выкрутиться, но у тебя не получается :-)

Если strlen(string) может хоть в бесконечный цикл уйти в определенных экзотических условиях, ну или дать segfault

Фантазии уровня ученика средней школы меня мало впечатляют :-) Никаких экзотических условий выполнения такой примитивной функции, как strlen() нет :-) Ей всего лишь надо передать правильную C-строку, и эта функция вернёт её размер - читай количество итераций :-) Лол :-)

пока с тебя и этого хватило

Засчитано :-)

anonymous
()
Ответ на: комментарий от andreyu

Неужели?

Ну да :-) Вы и показали :-)

А как, по вашему, в моем профиле что-то появилось?

Вы и добавили :-) Лол :-)

Целых 2 лишних вопроса :-)

anonymous
()
Ответ на: комментарий от andreyu

Если упереться именно в тот пример, то переписать его можно так: vec.clear();

Нет, так нельзя. В том примере очищалась только половина вектора. Можно, конечно, оптимизировать средствами stl, урезав уже после цикла одним вызовом, но именно урезав, а не полностью очистив.

Но если в цикле появится условие (а иначе какой смысл копировать

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

элемент в самого себя, а потом его удалять?)

Ну, копируется он в самого себя только на первой итерации.

if (vec[idx].readyToRemove())

То ваше «следовало бы в соответствии с рекомендациями K&R переписать так:» становится неверным.

Согласен. В принципе, можно было бы вынести проверку readyToRemove() в заголовок цикла, оставшись верным принципам K&R, но могло бы получиться совсем коряво, а главное, что вместо одной проверки мы получили бы 2 абсолютно одинаковые проверки readyToRemove() на каждой итерации: одну в условии цикла, а другую — внутри. Как сказал анонимус, в таком случае можно было бы использовать цикл while, но это дело вкуса. Имхо, любые рекомендации по стилю программирования всегда остаются рекомендациями, из которых в каждом конкретном случае можно сделать исключение. Главное, чтобы этих исключений было не слишком много.

В любом случае, в топике речь о языке C++ от Б. Страуструпа, а не о языке C от Б. Кернигана и Д. Ритчи.

Я же отвечал не на верхний пост, а на конкретную реплику в треде. Ну и циклы for у Страуструпа и K&R ничем не отличаются (всякие там foreach — уже более позднее новшество). И, повторюсь, я не считаю достаточным аргументом в споре ссылку на мнение любого авторитета, будь то Ритчи, Страуструп, Столлман или Торвальдс, если мнение это не обосновывается. Речь в этой подветке разговора шла о стиле программирования, и мнение как Ритчи, так и Страуструпа, может учитываться только в том случае, если оно обосновано чем-то, помимо известного имени автора.

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

aureliano15 ★★
()
Ответ на: комментарий от anonymous

Целых 2 лишних вопроса :-)

Эти два «лишних» вопроса имели цель донести до вас, что о коде моих проектов вы судите исключительно по одному проекту.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от aureliano15

Лично мне не понравилась неуместная отсылка к Кернигану и Ритчи

Вообще-то отсылка к K&R была специально для специалиста, который мне пытался доказать, что в Си for - это while :-) Видимо, он где-то слышал подобный сказ, и решил его мне озвучить :-) В ответ он был послан обратиться к главе 3.5 отличной книги от K&R, вот так:

В C for - это for :-) За пруфом читать K&R, глава 3.5 :-) Там же можно обнаружить рекомендации когда следует предпочесть for - когда есть простая инициализация и инкрементирование переменных цикла :-)

А вот это:

Т.е. когда число итераций заведомо известно :-)

является моим личным выводом :-)

anonymous
()
Ответ на: комментарий от andreyu

Если упереться именно в тот пример, то переписать его можно так:

vec.clear();

Да ты и сам не понял, что делает написанный тобой код! :-)

i-rinat ★★★★★
()
Ответ на: комментарий от aureliano15

Нет, так нельзя. В том примере очищалась только половина вектора. Можно, конечно, оптимизировать средствами stl, урезав уже после цикла одним вызовом, но именно урезав, а не полностью очистив.
Пример сам по себе надуманный,

Этот снипет кода был ответом на вопрос «Зачем вручную выполнять его работу?».

А так да, лучше приводить более реальные примеры. Однако не всегда они приходят в голову, особенно простые.

Согласен.

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

Ну аноним считает иначе - только его стиль исключительно правильный и имеющий право на жизнь.

А с вами — в том, что из любого правила бывают исключения.

Снова соглашусь с вами.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Да ты и сам не понял, что делает написанный тобой код! :-)

Вы меня поймали, я никогда не знал, что делает мой код.

andreyu ★★★★★
() автор топика
Ответ на: комментарий от andreyu

Эти два «лишних» вопроса имели цель донести до вас, что о коде моих проектов вы судите исключительно по одному проекту.

Не верно :-) По одному проекту, что в вашем профиле, можно судить о вашем профиле на bitbucket :-) А там не один проект :-)

Вы пишите вполне читаемый код :-) И очень аккуратный :-) Жаль, конечно, что на это уходит много времени и работодатель-ламерок этот труд ценит мало :-)

anonymous
()
Ответ на: комментарий от anonymous

А там не один проект :-)

Там их гораздо больше, но 90+% приватные.

Жаль, конечно, что на это уходит много времени и работодатель-ламерок этот труд ценит мало :-)

Откуда вы знаете, где я работаю?

andreyu ★★★★★
() автор топика
Ответ на: комментарий от andreyu

я никогда не знал, что делает мой код.

Это очень хорошая иллюстрация моего тезиса. Разбираться в таком коде — долго и нудно. Это пример трюкачества в духе: «смотрите, как я могу». Писать так код — неправильно. Если и автор не может понять, что делает код, чего уж говорить об остальных?

i-rinat ★★★★★
()
Ответ на: комментарий от andreyu

Там их гораздо больше, но 90+% приватные.

Я не сомневаюсь в вашей продуктивности :-)

Откуда вы знаете, где я работаю?

Я не знаю, где вы работаете :-) Я знаю, что работодателям-ламеркам всё равно насколько аккуратно написан код :-) Они совершенно не понимают что такое аккуратно написанный код :-) Другое дело, работодатель, который сам является программистом :-) Но это ему надо быть хорошим программистом :-) Остальным всё равно :-)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.