Здравствуйте, VladD2, Вы писали:
544>>как в foreach узнать "номер" текущей итерации? VD>Если нужен счетчик и коллекция поддерживает доступ по индексу, то проще обойтись for-ом.
Проще, но не факт, что лучше. Сложность доступа по индексу O(f(n)) может быть совершенно другой, чем получение всех элементов в произвольном порядке.
... << RSDN@Home 1.1.4 beta 4 rev. 310>>
"Develop with pleasure!"
Re[3]: foreach
От:
Аноним
Дата:
04.03.05 11:26
Оценка:
Здравствуйте, orangy, Вы писали:
O>Здравствуйте, VladD2, Вы писали:
544>>>как в foreach узнать "номер" текущей итерации? VD>>Если нужен счетчик и коллекция поддерживает доступ по индексу, то проще обойтись for-ом. O>Проще, но не факт, что лучше. Сложность доступа по индексу O(f(n)) может быть совершенно другой, чем получение всех элементов в произвольном порядке.
Кстати а нет ли где-то сводной таблицы с оценками производительности по разным структурам?
Здравствуйте, orangy, Вы писали:
O>Проще, но не факт, что лучше. Сложность доступа по индексу O(f(n)) может быть совершенно другой, чем получение всех элементов в произвольном порядке.
Это из разряда гипотетических предположений. Большинство коллекций имеют константное время доступа. Ну, или логарифмическое, что тоже для большинства применений фигня. Но думать что делаешь всегда полезно.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
O>>Проще, но не факт, что лучше. Сложность доступа по индексу O(f(n)) может быть совершенно другой, чем получение всех элементов в произвольном порядке. VD>Это из разряда гипотетических предположений. Большинство коллекций имеют константное время доступа. Ну, или логарифмическое, что тоже для большинства применений фигня. Но думать что делаешь всегда полезно.
Влад, ну это же чушь?! Покажи мне список с хотя бы логарифмическим доступом по индексу? Или даже для B-дерева, если не вводить аггрегатных состояний в узлах (сколько descendants у него)?
Или ты считаешь, что кроме стандартных коллекций FCL других не существует?
Здравствуйте, 55aaf925-4dbf-4578-9e3c-2f63d11aeda5, Вы писали:
544>как в foreach узнать "номер" текущей итерации?
Только вручную. Полученный enumerator не обязан работать простым перебором итемов. Это может быть и обход дерева и т.д. и т.п. Вызывающий код, информацией о работе итератора иметь не обязан (в этом смысл паттерна).
Здравствуйте, orangy, Вы писали:
O>Влад, ну это же чушь?!
Да? Во оно как...
O> Покажи мне список с хотя бы логарифмическим доступом по индексу?
90% коллекций вообще имеют константное время. Во фрэймворке я других и не припомню.
O> Или даже для B-дерева, если не вводить аггрегатных состояний в узлах (сколько descendants у него)?
Ты сам-то понял что сказал?
O>Или ты считаешь, что кроме стандартных коллекций FCL других не существует?
Когда человек говорит о доступе к ... скорее всего он имеет в виду как раз стандартные коллекции. Да и не стандартность еще не означет, что характиристики доступа по индексу будет не константными. Бывает конечно по всякому, но все же коллекции с неконстантным доступом скорее экзотика. Потому и говорю, что это скорее гипететическое замечание.
К тому же я вроде скзал, что всегда нужно думать головой. Если орел будет производить индексированный доступ к связанному списку (автор которого с дури разрешил подобную операцию), то этот орел сам себе злобный буратина.
Однако городить огород из foreach с дополнительным счетчиком только из-за перестраховок — глупо. В большинстве случаев доступ по индексу будет быстрее использования перечислителей. Дополнительный счетчик тоже положительного влияния не оказывает.
Ты вот лучше скажи сколько в твоих программах переборов фрэймворковских коллекций и массивов, а сколько не стандартных у которых время доступа к элементу неконстантно?
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
O>> Покажи мне список с хотя бы логарифмическим доступом по индексу? VD>90% коллекций вообще имеют константное время.
Доступа по индексу?
VD> Во фрэймворке я других и не припомню.
Фреймворком жизнь не ограничивается. В нем вообще бедный набор коллекций.
VD>К тому же я вроде скзал, что всегда нужно думать головой.
С этим я всегда согласен
VD>Однако городить огород из foreach с дополнительным счетчиком только из-за перестраховок — глупо. В большинстве случаев доступ по индексу будет быстрее использования перечислителей. Дополнительный счетчик тоже положительного влияния не оказывает.
Дополнительный счетчик это ерунда. А вот помнить о сложностях операций над коллекциями — важно.
VD>Ты вот лучше скажи сколько в твоих программах переборов фрэймворковских коллекций и массивов, а сколько не стандартных у которых время доступа к элементу неконстантно?
Честно говоря, не считал. Естественно, "простые" коллекции вроде ArrayList (само название-то какое!) используются гораздо чаще, и дело тут, конечно, не во фреймворке. Однако у меня довольно много сложных коллекций и вообще структур данных поддерживающих IEnumerable, и у большинства доступ по индексу не константный, буде таковой определен.
Здравствуйте, orangy, Вы писали:
VD>>90% коллекций вообще имеют константное время. O>Доступа по индексу?
У тебя или что-то с информацией, или с терпинологией.
VD>> Во фрэймворке я других и не припомню. O>Фреймворком жизнь не ограничивается. В нем вообще бедный набор коллекций.
Этого бедного для большинства задаче более чем достаточно. Ну, а там уже нужно голову включать.
O>С этим я всегда согласен
Ну, а что тогда буянишь?
Если коллекция сделано с головой, то при неконстантном доступе скорее всего она не будет предоставлять доступа по целочисленному индексу. Хотя конечно — это не факт.
O>Дополнительный счетчик это ерунда. А вот помнить о сложностях операций над коллекциями — важно.
Надо не помнить, а думать. Если сомнения одалевают, то заглядывать в хэлп или исходники. Да и вообще — это очередная забота о скорости на ровном месте. Если будет тормозить доступ к коллекции, то это любой профайлер покажет.
А вот грязь в коде — это проблема с которой сталкиваешся постоянно и везде. И чем меньше ее будет тем лучше. Делать индексы в foreach-ах для дотнетных коллекций — это полный идеотизм.
O>Честно говоря, не считал. Естественно, "простые" коллекции вроде ArrayList (само название-то какое!) используются гораздо чаще, и дело тут, конечно, не во фреймворке.
А вот у меня ArrayList хрен найдешь. Если только в реализации коллекции. Уж лучше наклепать коллекцию типизированную, чем лепить всюду приведения.
O> Однако у меня довольно много сложных коллекций и вообще структур данных поддерживающих IEnumerable, и у большинства доступ по индексу не константный, буде таковой определен.
Можно узнать их названия и назначение?
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>А вот грязь в коде — это проблема с которой сталкиваешся постоянно и везде. И чем меньше ее будет тем лучше. Делать индексы в foreach-ах для дотнетных коллекций — это полный идеотизм.
Не будь столь категоричен. По грязности оба способа одинаковы. В foreach несколько размазан код счетчика, в for вылезет приведение. Сравни:
int i = 0;
foreach (SomeObject so in list)
{
so.SomeMethod();
i++;
}
//----------------------------------for (int i = 0; i < list.Count; i++)
{
SomeObject so = (SomeObject)list[i];
so.SomeMethod();
}
Как видишь — кардинальных различий в грязности нет. Кроме того, первый вариант универсальнее, поскольку способен работать только с IEnumerable или даже без него, а вот второму нужен обязательно IList. И необходимость в таком варианте отнюдь не эфемерна. Даже если не привлекать к рассмотрению некие мифические коллекции, в самом фреймворке можно найти таких коллекций предостаточно. Например Hashtable, Hashtable.Keys, Hashtable.Values, BindingContext, System.Web.Caching.Cache, CredentialsCache, ListDictionary, Stack, Queue и много много других.
Здравствуйте, VladD2, Вы писали:
VD>>>90% коллекций вообще имеют константное время. O>>Доступа по индексу? VD>У тебя или что-то с информацией, или с терпинологией.
Перечитай ветку. Мне кажется, ты где-то потерял нить разговора. Ну или я не понял, что ты хотел сказать этой фразой. Тогда расшифруй.
VD>>> Во фрэймворке я других и не припомню. O>>Фреймворком жизнь не ограничивается. В нем вообще бедный набор коллекций. VD>Этого бедного для большинства задаче более чем достаточно. Ну, а там уже нужно голову включать.
Чтобы включать голову, нужно хотя бы знать, что здесь может быть разница. О чём я, собственно, и намекнул в самом начале. Я не говорил о достаточности или не достаточности коллекций в FCL, о их реализации. К сожалению, многие приходящие на собеседование начинают лепить ассоциативные массивы (буде им дана такая задача) на двух параллельных массивах, даже не отсортированых. Ни в коей мере не подозревая тебя в таком подходе, я всего лишь хотел заострить внимание на одном и только одном факте: не все коллекции одинаковы
O>>Дополнительный счетчик это ерунда. А вот помнить о сложностях операций над коллекциями — важно. VD>Надо не помнить, а думать. Если сомнения одалевают, то заглядывать в хэлп или исходники. Да и вообще — это очередная забота о скорости на ровном месте. Если будет тормозить доступ к коллекции, то это любой профайлер покажет.
Вот здесь мы с тобой кардинально расходимся в подходах. Но флейм разводить не будем.
VD>А вот грязь в коде — это проблема с которой сталкиваешся постоянно и везде. И чем меньше ее будет тем лучше. Делать индексы в foreach-ах для дотнетных коллекций — это полный идиотизм.
Ставить чистоту кода выше его логичности — вот полный идиотизм. Это мне напомнило требования к чистоте в армии
O>>Честно говоря, не считал. Естественно, "простые" коллекции вроде ArrayList (само название-то какое!) используются гораздо чаще, и дело тут, конечно, не во фреймворке. VD>А вот у меня ArrayList хрен найдешь. Если только в реализации коллекции. Уж лучше наклепать коллекцию типизированную, чем лепить всюду приведения.
Придираешься. Пропускаем.
O>> Однако у меня довольно много сложных коллекций и вообще структур данных поддерживающих IEnumerable, и у большинства доступ по индексу не константный, буде таковой определен. VD>Можно узнать их названия и назначение?
Зачем? Их дольше описывать, нежели поверить мне на слово Как пример приведу лишь ConfigurationNodeCollection, поддерживающая перечисление дочерних узлов. Проблема с этой коллекцией состоит в том, что информация собирается из разных ConfigurationProvider-ов динамически, которые в свою очередь подмонтированы в произвольные узлы дерева конфигурации. В пределах одной "версии" системы конфигурации (всмысле, пока нет изменений) гарантируется порядок элементов, но операция взятия по индексу — не константна. Эта операция и нужна-то только в паре сценариев, и я даже думаю выкинуть её нафик — именно потому, что её наличие может смутить конечных пользователей и сбить их с понимания истинной сложности операции.
Здравствуйте, AndrewVK, Вы писали:
AVK>Не будь столь категоричен. По грязности оба способа одинаковы. В foreach несколько размазан код счетчика, в for вылезет приведение. Сравни: AVK>
AVK>int i = 0;
AVK>foreach (SomeObject so in list)
AVK>{
AVK> so.SomeMethod();
AVK> i++;
AVK>}
AVK>//----------------------------------
AVK>for (int i = 0; i < list.Count; i++)
AVK>{
AVK> SomeObject so = (SomeObject)list[i];
AVK> so.SomeMethod();
AVK>}
AVK>
Притянутый за уши пример. Даже его можно переписать по человечески:
for (int i = 0; i < list.Count; i++)
((SomeObject)list[i]).SomeMethod();
А вообще нужно поменьше использовать нетипизированных коллекций итогда прийтеся меньше прятать приведения типов за foreach-ем. В подобных случаях я хотя бы стараюсь использовать функции приводящие типы. Там хоть контроль локализуется в одном месте.
AVK>Как видишь — кардинальных различий в грязности нет.
Влепил привдение типов и пыташся за его грязью замаскировать другую.
AVK> Кроме того, первый вариант универсальнее, поскольку способен работать только с IEnumerable или даже без него,
А так же тормознее во многих случаях.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Притянутый за уши пример.
Ну тогда тебе вполне конкретный пример — напиши ка ты код, пробегающий по ключам хештаблицы с индексом.
VD> Даже его можно переписать по человечески: VD>
VD>for (int i = 0; i < list.Count; i++)
VD> ((SomeObject)list[i]).SomeMethod();
VD>
Забавно от тебя слышать подобный аргумент. Ты всерьез считаешь что после такого преобразования код стал проще? Так я тоже могу как нибудь так переписать:
int i = 0;
foreach (SomeObject so in list)
so.SomeMethod(i++);
VD>А вообще нужно поменьше использовать нетипизированных коллекций
Да-да. Особенно с релизными фреймворками. И каждый раз, когда нужно временно что то в список напихать создавать под это типизированную коллекцию.
AVK>>Как видишь — кардинальных различий в грязности нет. VD>Влепил привдение типов и пыташся за его грязью замаскировать другую.
Ну да, конечно, раз пример неудобен для твоей точки зрения значит он плохой. Открой код того же януса и убедись в том, что foreach с приведением там море, в том числе и в написанном тобой коде.
AVK>> Кроме того, первый вариант универсальнее, поскольку способен работать только с IEnumerable или даже без него,
VD>А так же тормознее во многих случаях.
Да-да. При условии отсуствия доступа по индексу у коллекции в принципе доступ через foreach конечно же тормознее for .