Manakah dari berikut ini yang lebih cepat / lebih baik?
Yang ini:
List<User> list = new List<User>();
User u;
foreach (string s in l)
{
u = new User();
u.Name = s;
list.Add(u);
}
Atau yang ini:
List<User> list = new List<User>();
foreach (string s in l)
{
User u = new User();
u.Name = s;
list.Add(u);
}
Keterampilan pengembangan pemula saya memberi tahu saya bahwa yang pertama lebih baik, tetapi seorang teman saya memberi tahu saya bahwa saya salah, tetapi tidak dapat memberi saya alasan yang baik mengapa yang kedua lebih baik.
Apakah ada perbedaan kinerja sama sekali?
Bagaimanapun, cara terbaik adalah menggunakan konstruktor yang menggunakan Nama ... atau, jika tidak, gunakan notasi kurung kurawal:
foreach (string s in l) { list.Add(new User(s)); }
atau
foreach (string s in l) { list.Add(new User() { Name = s }); }
atau bahkan lebih baik, LINQ:
var list = l.Select( s => new User { Name = s});
Sekarang, sementara contoh pertama Anda dapat, dalam beberapa kasus, tidak terlihat lebih cepat, yang kedua lebih baik karena lebih mudah dibaca, dan kompilator mungkin membuang variabel (dan menghilangkannya sama sekali) karena tidak digunakan
foreach
di luar ruang lingkup.sumber
Deklarasi tidak menyebabkan kode apa pun dijalankan, jadi ini bukan masalah kinerja.
Yang kedua adalah yang Anda maksud, dan Anda cenderung tidak membuat kesalahan bodoh jika Anda melakukannya dengan cara kedua, jadi gunakan itu. Selalu mencoba untuk mendeklarasikan variabel dalam ruang lingkup terkecil yang diperlukan.
Dan selain itu, cara yang lebih baik adalah dengan menggunakan LINQ:
List<User> users = l.Select(name => new User{ Name = name }).ToList();
sumber
Kapan pun Anda memiliki pertanyaan tentang kinerja, satu-satunya hal yang harus dilakukan adalah mengukur - menjalankan pengujian dan menghitung waktunya.
Untuk menjawab pertanyaan Anda - tanpa mengukur :-) atau melihat ilasm yang dihasilkan - perbedaan apa pun tidak akan terlihat dalam sejumlah iterasi yang berarti dan operasi yang paling mahal dalam kode Anda kemungkinan besar adalah alokasi pengguna dengan beberapa pesanan besarnya, jadi berkonsentrasilah pada kejelasan kode (sebagaimana seharusnya secara umum) dan lanjutkan dengan 2.
Oh, ini terlambat dan saya rasa saya hanya mencoba mengatakan jangan khawatir tentang hal semacam ini atau terjebak dalam detail seperti ini.
K
sumber
Yang kedua lebih baik. Anda bermaksud memiliki pengguna baru di setiap iterasi.
sumber
Secara teknis, contoh pertama akan menghemat beberapa nanodetik karena stack frame tidak perlu dipindahkan untuk mengalokasikan variabel baru, tetapi ini adalah jumlah waktu CPU yang sangat kecil sehingga Anda tidak akan menyadarinya, itu jika kompiler tidak mengoptimalkan perbedaan jauh anyays.
sumber
Dalam skenario ini, versi kedua lebih baik.
Secara umum, jika Anda hanya perlu mengakses nilai di dalam badan iterasi, pilih versi kedua. Di sisi lain, jika ada beberapa status akhir yang akan ditahan variabel di luar badan perulangan, kemudian deklarasikan kemudian gunakan versi pertama.
sumber
Seharusnya tidak ada perbedaan kinerja yang bisa dilihat.
sumber
Referensi lain yang terlihat seperti di atas:
http://social.msdn.microsoft.com/forums/en-US/csharplanguage/thread/d43aaba5-a58b-4610-bea4-5bc5d6741f98
sumber
Saya pergi untuk memverifikasi masalah ini. Secara mengejutkan mengetahui dari tes kotor saya bahwa opsi ke-2 bahkan sedikit lebih cepat sepanjang waktu.
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; } }
Saya memverifikasi CIL tetapi tidak identik.
Jadi saya mempersiapkan sesuatu yang saya ingin tes menjadi lebih baik.
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 { } }
Juga dalam kasus ini metode ke-2 selalu menang tetapi kemudian saya memverifikasi CIL tidak menemukan perbedaan.
Saya bukan ahli membaca CIL tetapi saya tidak melihat masalah deklerasi. Seperti yang telah ditunjukkan, deklarasi bukanlah alokasi sehingga tidak ada hukuman kinerja di atasnya.
Uji
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; }
sumber