РЕДАКТИРОВАТЬ Дополнительные параметры и немного расширенный вопрос ниже.
Рассмотрим этот надуманный и абстрактный пример тела класса. Он демонстрирует четыре различных способа выполнения итерации «для».
private abstract class SomeClass
{
public void someAction();
}
void Examples()
{
List<SomeClass> someList = new List<SomeClass>();
//A. for
for (int i = 0; i < someList.Count(); i++)
{
someList[i].someAction();
}
//B. foreach
foreach (SomeClass o in someList)
{
o.someAction();
}
//C. foreach extension
someList.ForEach(o => o.someAction());
//D. plinq
someList.AsParallel().ForAll(o => o.someAction());
РЕДАКТИРОВАТЬ: Добавление некоторых вариантов из ответов и исследований.
//E. ParallelEnumerable
ParallelEnumerable.Range(0, someList.Count - 1)
.ForAll(i => someList[i].someAction());
//F. ForEach Parallel Extension
Parallel.ForEach(someList, o => o.someAction());
//G. For Parallel Extension
Parallel.For(0, someList.Count - 1, i => someList[i].someAction())
}
Мой вопрос состоит из двух частей. Не упустил ли я какой-то важный вариант? Какой вариант лучше всего с учетом удобочитаемости, но в первую очередь производительности?
Пожалуйста, укажите, повлияет ли на этот выбор сложность реализации SomeClass
или Count
из someList
.
EDIT: такое головокружительное множество вариантов, я бы не хотел, чтобы мой код был испорчен выбором. Чтобы добавить третью часть к моему вопросу: «Если мой список может быть любой длины, следует ли мне по умолчанию использовать параллельный вариант?»
Как соломенный человек. Я подозреваю, что во всех реализациях SomeClass
и во всех длинах someList
option // E. ParallelEnumerable
обеспечит наилучшую среднюю производительность, учитывая преобладание многопроцессорных архитектур. Я не проводил никаких тестов, чтобы доказать это.
Примечание: параллельные расширения потребуют использования пространства имен System.Threading.Tasks
.