Каков наилучший способ перебора строго типизированного универсального List<T>?
Как лучше всего выполнить итерацию по строго 9X_c-sharp типизированному общему списку в C#.NET и 9X_c#.net VB.NET?
Ответ #1
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
Для С#:
foreach(ObjectType objectItem in objectTypeList) { // ...do some stuff }
Ответ для VB.NET от Purple Ant:
For Each objectItem as ObjectType in objectTypeList 'Do some stuff ' Next
9X_.net-framework
- Поскольку он строго типизирован, вы также можете использовать: `foreach (var i ...
Ответ #2
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
С любой универсальной реализацией IEnumerable 9X_java-generics лучший способ:
//C# foreach( var item in listVariable) { //do stuff }
Однако есть важное исключение. IEnumerable 9X_c-sharp включает накладные расходы на Current() и 9X_collection MoveNext(), то есть то, во что фактически 9X_vbproj скомпилирован цикл foreach.
Если у вас есть 9X_generics простой массив структур:
//C# int[] valueTypeArray; for(int i=0; i < valueTypeArray.Length; ++i) { int item = valueTypeArray[i]; //do stuff }
Быстрее.
Обновление
После обсуждения 9X_c#.net с @Steven Sudit (см. комментарии) я думаю, что 9X_vbproj мой первоначальный совет может быть устаревшим 9X_generic или ошибочным, поэтому я провел несколько 9X_c-sharp тестов:
// create a list to test with var theList = Enumerable.Range(0, 100000000).ToList(); // time foreach var sw = Stopwatch.StartNew(); foreach (var item in theList) { int inLoop = item; } Console.WriteLine("list foreach: " + sw.Elapsed.ToString()); sw.Reset(); sw.Start(); // time for int cnt = theList.Count; for (int i = 0; i < cnt; i++) { int inLoop = theList[i]; } Console.WriteLine("list for : " + sw.Elapsed.ToString()); // now run the same tests, but with an array var theArray = theList.ToArray(); sw.Reset(); sw.Start(); foreach (var item in theArray) { int inLoop = item; } Console.WriteLine("array foreach: " + sw.Elapsed.ToString()); sw.Reset(); sw.Start(); // time for cnt = theArray.Length; for (int i = 0; i < cnt; i++) { int inLoop = theArray[i]; } Console.WriteLine("array for : " + sw.Elapsed.ToString()); Console.ReadKey();
Итак, я запустил это в релизе со 9X_c-sharp всеми оптимизациями:
list foreach: 00:00:00.5137506 list for : 00:00:00.2417709 array foreach: 00:00:00.1085653 array for : 00:00:00.0954890
А потом отлаживать без 9X_collections оптимизаций:
list foreach: 00:00:01.1289015 list for : 00:00:00.9945345 array foreach: 00:00:00.6405422 array for : 00:00:00.4913245
Таким образом, это кажется довольно 9X_java-generics последовательным, for
быстрее, чем foreach
, а массивы 9X_c-sharp быстрее, чем общие списки.
Однако это происходит 9X_dot-net через 100 000 000 итераций, и разница составляет 9X_generic около 0,4 секунды между самым быстрым и 9X_java-collections-api самым медленным методами. Если вы не выполняете 9X_c#.net массивные критические циклы производительности, об 9X_generics этом просто не стоит беспокоиться.
- Позвольте мне поблагодарить вас за тяжелую работу, но я должен упомянуть, что у моих тестов было одно ключевое отличие: я ...
Ответ #3
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
С#
myList().ForEach( delegate(string name) { Console.WriteLine(name); });
Анонимные делегаты в настоящее время не 9X_.net-framework реализованы в VB.Net, но и C#, и VB.Net 9X_.net должны уметь выполнять лямбда-выражения:
С#
myList().ForEach(name => Console.WriteLine(name));
ВБ.Нет
myList(Of String)().ForEach(Function(name) Console.WriteLine(name))
Как 9X_.net заметил Грауэнвольф, приведенный выше VB 9X_vb.net не будет компилироваться, поскольку лямбда 9X_c-sharp не возвращает значение. Обычный цикл ForEach, как 9X_vbproj предлагали другие, на данный момент, вероятно, самый 9X_c#.net простой, но, как обычно, требуется блок 9X_.net кода, чтобы сделать то, что С# может сделать 9X_c-sharp в одной строке.
Вот банальный пример того, почему 9X_.net-framework это может быть полезно: это дает вам возможность 9X_dotnet передавать логику цикла из другой области, отличной 9X_vb.net от той, где существует IEnumerable, поэтому 9X_c# вам даже не нужно выставлять ее, если вы 9X_dotnet этого не хотите.
Допустим, у вас есть список 9X_csharp относительных URL-адресов, которые вы хотите 9X_vbproj сделать абсолютными:
public IEnumerable Paths(Func formatter) { List paths = new List() { "/about", "/contact", "/services" }; return paths.ForEach(formatter); }
Тогда вы могли бы вызвать 9X_dot-net функцию следующим образом:
var hostname = "myhost.com"; var formatter = f => String.Format("http://{0}{1}", hostname, f); IEnumerable absolutePaths = Paths(formatter);
Предоставление 9X_vbproj вам "http://myhost.com/about", "http://myhost.com/contact"
и т. д. Очевидно, что есть лучшие способы 9X_java-collections-api сделать это в этом конкретном примере, я 9X_generic просто пытаюсь продемонстрировать основной 9X_generics принцип.
Ответ #4
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
Для VB.NET:
For Each tmpObject as ObjectType in ObjectTypeList 'Do some stuff ' Next
9X_csharp
Ответ #5
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
Не зная внутренней реализации списка, я 9X_vb думаю, что лучшим способом перебора списка 9X_vb будет цикл foreach. Поскольку foreach использует 9X_c#.net IEnumerator для обхода списка, сам список 9X_c#.net определяет, как переходить от объекта к 9X_collections объекту.
Если бы внутренней реализацией был, скажем, связанный 9X_c# список, то простой цикл for был бы немного 9X_collection медленнее, чем foreach.
Имеет ли это смысл?
Ответ #6
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
Это зависит от вашего приложения:
- цикл for, если эффективность является приоритетом
- цикл foreach или метод ForEach, в зависимости от того, что более четко передает ваши намерения
9X_vbproj
Ответ #7
Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?
Я могу что-то упустить, но повторение общего 9X_collection списка должно быть довольно простым, если 9X_.net вы используете мои примеры ниже. Класс List<> реализует 9X_dot-net интерфейсы IList и IEnumerable, так что 9X_collections вы можете легко перебирать их практически 9X_dotnet любым удобным для вас способом.
Наиболее 9X_generics эффективным способом было бы использование 9X_dotnet цикла for:
for(int i = 0; i < genericList.Count; ++i) { // Loop body }
Вы также можете использовать цикл 9X_generic foreach:
foreach( o in genericList) { // Loop body }
-
3
-
3
-
5
-
5
-
7
-
2
-
2
-
8
-
6
-
9
-
5
-
3
-
4
-
10
-
3
-
5
-
5
-
5
-
2
-
7
-
11
-
3
-
5
-
2
-
2
-
7
-
7
-
11
-
4
-
11
-
17
-
7
-
4
-
14
-
2
-
5
-
4
-
6
-
2
-
6
-
2
-
5
-
8
-
3
-
3
-
2
-
3
-
5
-
3
-
3