Каков наилучший способ перебора строго типизированного универсального 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