เนื่องจากฉันมีคำถามคล้ายกันทำให้ฉันเริ่มต้นได้อย่างรวดเร็ว
คำถามของฉันค่อนข้างเจาะจงมากขึ้น 'อะไรคือวิธีที่เร็วที่สุดสำหรับการปรับใช้อาเรย์แบบสะท้อนกลับ'
การทดสอบที่ทำโดย Marc Gravell แสดงให้เห็นเป็นอย่างมาก แต่ไม่ใช่เวลาเข้าถึง เวลาของเขารวมถึงการวนลูปมากกว่าอาร์เรย์และรายการเช่นกัน ตั้งแต่ฉันขึ้นมาด้วยวิธีที่สามที่ฉันต้องการทดสอบ 'พจนานุกรม' เพื่อเปรียบเทียบฉันขยายรหัสทดสอบ hist
Firts ฉันทำการทดสอบโดยใช้ค่าคงที่ซึ่งทำให้ฉันมีเวลารวมถึงลูป นี่เป็นเวลา 'เปล่า' ไม่รวมการเข้าถึงจริง จากนั้นฉันทำการทดสอบด้วยการเข้าถึงโครงสร้างเรื่องสิ่งนี้ทำให้ฉันและ 'รวมค่าใช้จ่าย' เวลาลูปและการเข้าถึงจริง
ความแตกต่างระหว่างการกำหนดเวลาแบบ 'เปล่า' และการกำหนดเวลาแบบ 'เหนือศีรษะ' ทำให้ฉันบ่งบอกถึงการกำหนดเวลาแบบ 'เข้าถึงโครงสร้าง'
แต่เวลานี้แม่นยำแค่ไหน? ในระหว่างการทดสอบหน้าต่างจะทำการแบ่งเวลาเพื่อ shure ฉันไม่มีข้อมูลเกี่ยวกับการแบ่งเวลา แต่ฉันเชื่อว่ามีการกระจายอย่างเท่าเทียมกันในระหว่างการทดสอบและตามลำดับเป็นสิบมิลลิวินาทีซึ่งหมายความว่าความแม่นยำสำหรับการกำหนดเวลาควรอยู่ในลำดับ +/- 100 msec หรือมากกว่านั้น ประมาณการคร่าวๆ? อย่างไรก็ตามแหล่งที่มาของข้อผิดพลาดที่เป็นระบบ
นอกจากนี้ยังทำการทดสอบในโหมด 'Debug' โดยไม่มีการปรับให้เหมาะสม มิฉะนั้นคอมไพเลอร์อาจเปลี่ยนรหัสทดสอบจริง
ดังนั้นฉันได้รับผลลัพธ์สองรายการหนึ่งรายการสำหรับค่าคงที่ทำเครื่องหมาย '(c)' และอีกรายการหนึ่งสำหรับการเข้าถึงที่มีเครื่องหมาย '(n)' และความแตกต่าง 'dt' จะบอกฉันว่าใช้เวลาเข้าถึงจริงเท่าใด
และนี่คือผลลัพธ์ที่ได้:
Dictionary(c)/for: 1205ms (600000000)
Dictionary(n)/for: 8046ms (589725196)
dt = 6841
List(c)/for: 1186ms (1189725196)
List(n)/for: 2475ms (1779450392)
dt = 1289
Array(c)/for: 1019ms (600000000)
Array(n)/for: 1266ms (589725196)
dt = 247
Dictionary[key](c)/foreach: 2738ms (600000000)
Dictionary[key](n)/foreach: 10017ms (589725196)
dt = 7279
List(c)/foreach: 2480ms (600000000)
List(n)/foreach: 2658ms (589725196)
dt = 178
Array(c)/foreach: 1300ms (600000000)
Array(n)/foreach: 1592ms (589725196)
dt = 292
dt +/-.1 sec for foreach
Dictionary 6.8 7.3
List 1.3 0.2
Array 0.2 0.3
Same test, different system:
dt +/- .1 sec for foreach
Dictionary 14.4 12.0
List 1.7 0.1
Array 0.5 0.7
ด้วยการประมาณการที่ดีขึ้นเกี่ยวกับข้อผิดพลาดเกี่ยวกับเวลา (จะลบข้อผิดพลาดการวัดอย่างเป็นระบบเนื่องจากการแบ่งเวลาได้อย่างไร) อาจกล่าวเพิ่มเติมเกี่ยวกับผลลัพธ์ได้
ดูเหมือนว่ารายการ / foreach มีการเข้าถึงที่เร็วที่สุด แต่ค่าใช้จ่ายถูกฆ่า
ความแตกต่างระหว่าง List / for และ List / foreach คือ stange อาจจะมีบาง cashing เกี่ยวข้อง?
นอกจากนี้สำหรับการเข้าถึงอาร์เรย์มันไม่สำคัญว่าคุณจะใช้การfor
วนซ้ำหรือการforeach
วนซ้ำ ผลลัพธ์เวลาและความแม่นยำทำให้ผลลัพธ์ 'เปรียบเทียบได้'
การใช้พจนานุกรมนั้นช้าที่สุดฉันคิดเพียงเพราะทางด้านซ้าย (ตัวทำดัชนี) ฉันมีรายการจำนวนเต็มเล็กน้อยและไม่ใช่ช่วงที่ใช้ในการทดสอบนี้
นี่คือรหัสทดสอบที่แก้ไข
Dictionary<int, int> dict = new Dictionary<int, int>(6000000);
List<int> list = new List<int>(6000000);
Random rand = new Random(12345);
for (int i = 0; i < 6000000; i++)
{
int n = rand.Next(5000);
dict.Add(i, n);
list.Add(n);
}
int[] arr = list.ToArray();
int chk = 0;
Stopwatch watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
int len = dict.Count;
for (int i = 0; i < len; i++)
{
chk += 1; // dict[i];
}
}
watch.Stop();
long c_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" Dictionary(c)/for: {0}ms ({1})", c_dt, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
int len = dict.Count;
for (int i = 0; i < len; i++)
{
chk += dict[i];
}
}
watch.Stop();
long n_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" Dictionary(n)/for: {0}ms ({1})", n_dt, chk);
Console.WriteLine("dt = {0}", n_dt - c_dt);
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
int len = list.Count;
for (int i = 0; i < len; i++)
{
chk += 1; // list[i];
}
}
watch.Stop();
c_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" List(c)/for: {0}ms ({1})", c_dt, chk);
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
int len = list.Count;
for (int i = 0; i < len; i++)
{
chk += list[i];
}
}
watch.Stop();
n_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" List(n)/for: {0}ms ({1})", n_dt, chk);
Console.WriteLine("dt = {0}", n_dt - c_dt);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
for (int i = 0; i < arr.Length; i++)
{
chk += 1; // arr[i];
}
}
watch.Stop();
c_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" Array(c)/for: {0}ms ({1})", c_dt, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
for (int i = 0; i < arr.Length; i++)
{
chk += arr[i];
}
}
watch.Stop();
n_dt = watch.ElapsedMilliseconds;
Console.WriteLine("Array(n)/for: {0}ms ({1})", n_dt, chk);
Console.WriteLine("dt = {0}", n_dt - c_dt);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in dict.Keys)
{
chk += 1; // dict[i]; ;
}
}
watch.Stop();
c_dt = watch.ElapsedMilliseconds;
Console.WriteLine("Dictionary[key](c)/foreach: {0}ms ({1})", c_dt, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in dict.Keys)
{
chk += dict[i]; ;
}
}
watch.Stop();
n_dt = watch.ElapsedMilliseconds;
Console.WriteLine("Dictionary[key](n)/foreach: {0}ms ({1})", n_dt, chk);
Console.WriteLine("dt = {0}", n_dt - c_dt);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in list)
{
chk += 1; // i;
}
}
watch.Stop();
c_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" List(c)/foreach: {0}ms ({1})", c_dt, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in list)
{
chk += i;
}
}
watch.Stop();
n_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" List(n)/foreach: {0}ms ({1})", n_dt, chk);
Console.WriteLine("dt = {0}", n_dt - c_dt);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in arr)
{
chk += 1; // i;
}
}
watch.Stop();
c_dt = watch.ElapsedMilliseconds;
Console.WriteLine(" Array(c)/foreach: {0}ms ({1})", c_dt, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int rpt = 0; rpt < 100; rpt++)
{
foreach (int i in arr)
{
chk += i;
}
}
watch.Stop();
n_dt = watch.ElapsedMilliseconds;
Console.WriteLine("Array(n)/foreach: {0}ms ({1})", n_dt, chk);
Console.WriteLine("dt = {0}", n_dt - c_dt);