Какой из них быстрее / лучше?
Вот этот:
List<User> list = new List<User>();
User u;
foreach (string s in l)
{
u = new User();
u.Name = s;
list.Add(u);
}
Или вот этот:
List<User> list = new List<User>();
foreach (string s in l)
{
User u = new User();
u.Name = s;
list.Add(u);
}
Мои навыки развития новичков говорят мне, что первый лучше, но мой друг сказал мне, что я ошибаюсь, но не смог мне объяснить, почему второй лучше.
Есть ли вообще разница в производительности?
В любом случае, лучшим способом было бы использовать конструктор, который принимает имя ... или, иначе, использовать обозначение фигурных скобок:
foreach (string s in l) { list.Add(new User(s)); }
или
foreach (string s in l) { list.Add(new User() { Name = s }); }
или даже лучше, LINQ:
var list = l.Select( s => new User { Name = s});
Теперь, хотя ваш первый пример в некоторых случаях может быть незаметно быстрее, второй лучше, потому что он более читабелен, и компилятор может отбросить переменную (и опустить ее вообще), поскольку она не используется за пределами области
foreach
действия.источник
Объявление не вызывает выполнения какого-либо кода, поэтому это не проблема производительности.
Второе - это то, что вы имеете в виду, и у вас меньше шансов сделать глупую ошибку, если вы сделаете это вторым способом, поэтому используйте его. Всегда старайтесь объявлять переменные в минимально необходимом объеме.
Кроме того, лучше использовать Linq:
List<User> users = l.Select(name => new User{ Name = name }).ToList();
источник
Всякий раз, когда у вас возникает вопрос о производительности, единственное, что нужно сделать, - это измерить - запустить цикл вокруг вашего теста и установить время.
Чтобы ответить на ваш вопрос - без измерения :-) или просмотра сгенерированного ilasm - никакой разницы не будет заметно при значительном количестве итераций и самой дорогой операции в вашем коде, вероятно, будет распределение пользователей на несколько порядков значимости, поэтому сконцентрируйтесь на ясности кода (как и должно быть в целом) и используйте 2.
О, уже поздно, и я думаю, я просто пытаюсь сказать, не беспокойтесь о таких вещах и не вдавайтесь в подробности, подобные этим.
K
источник
Второй лучше. Вы хотите иметь нового пользователя на каждой итерации.
источник
Технически, первый пример сэкономит несколько наносекунд, потому что кадр стека не нужно будет перемещать для выделения новой переменной, но это настолько крошечное количество процессорного времени, что вы этого не заметите, если компилятор этого не сделает. оптимизируйте любую разницу в любом случае.
источник
В этом случае вторая версия лучше.
В общем, если вам нужно получить доступ только к значению в теле итерации, выберите вторую версию. С другой стороны, если есть какое-то конечное состояние, переменная будет удерживаться за пределами тела цикла, затем объявить, а затем использовать первую версию.
источник
Не должно быть ощутимой разницы в производительности.
источник
Еще одна ссылка, которая выглядит выше:
http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/d43aaba5-a58b-4610-bea4-5bc5d6741f98
источник
Я пошел проверить эту проблему. Удивительно, когда я обнаружил в своих грязных тестах, что второй вариант все время даже немного быстрее.
namespace Test { class Foreach { string[] names = new[] { "ABC", "MNL", "XYZ" }; void Method1() { List<User> list = new List<User>(); User u; foreach (string s in names) { u = new User(); u.Name = s; list.Add(u); } } void Method2() { List<User> list = new List<User>(); foreach (string s in names) { User u = new User(); u.Name = s; list.Add(u); } } } public class User { public string Name; } }
Я проверил CIL, но он не идентичен.
Итак, я подготовил кое-что, что я хотел сделать гораздо лучше.
namespace Test { class Loop { public TimeSpan method1 = new TimeSpan(); public TimeSpan method2 = new TimeSpan(); Stopwatch sw = new Stopwatch(); public void Method1() { sw.Restart(); C c; C c1; C c2; C c3; C c4; int i = 1000; while (i-- > 0) { c = new C(); c1 = new C(); c2 = new C(); c3 = new C(); c4 = new C(); } sw.Stop(); method1 = method1.Add(sw.Elapsed); } public void Method2() { sw.Restart(); int i = 1000; while (i-- > 0) { var c = new C(); var c1 = new C(); var c2 = new C(); var c3 = new C(); var c4 = new C(); } sw.Stop(); method2 = method2.Add(sw.Elapsed); } } class C { } }
Также в этом случае всегда был выигрыш 2-й метод, но затем я проверил CIL, не обнаружив разницы.
Я не гуру по чтению CIL, но не вижу проблем с отклонениями. Как уже отмечалось, объявление не является распределением, поэтому оно не снижает производительности.
Контрольная работа
namespace Test { class Foreach { string[] names = new[] { "ABC", "MNL", "XYZ" }; public TimeSpan method1 = new TimeSpan(); public TimeSpan method2 = new TimeSpan(); Stopwatch sw = new Stopwatch(); void Method1() { sw.Restart(); List<User> list = new List<User>(); User u; foreach (string s in names) { u = new User(); u.Name = s; list.Add(u); } sw.Stop(); method1 = method1.Add(sw.Elapsed); } void Method2() { sw.Restart(); List<User> list = new List<User>(); foreach (string s in names) { User u = new User(); u.Name = s; list.Add(u); } sw.Stop(); method2 = method2.Add(sw.Elapsed); } } public class User { public string Name; }
источник