Vì tôi có một câu hỏi tương tự, điều này đã cho tôi một khởi đầu nhanh chóng.
Câu hỏi của tôi cụ thể hơn một chút, 'phương pháp nhanh nhất để thực hiện mảng phản xạ là gì'
Các thử nghiệm được thực hiện bởi Marc Gravell cho thấy rất nhiều, nhưng không chính xác thời gian truy cập. Thời gian của anh ấy bao gồm các vòng lặp trên các mảng và danh sách là tốt. Vì tôi cũng đã đưa ra một phương pháp thứ ba mà tôi muốn thử nghiệm, một 'Từ điển', chỉ để so sánh, tôi đã mở rộng mã kiểm tra lịch sử.
Fumps, tôi làm một bài kiểm tra bằng cách sử dụng một hằng số, cho tôi một thời gian nhất định bao gồm cả vòng lặp. Đây là thời gian "trần", không bao gồm quyền truy cập thực tế. Sau đó, tôi thực hiện một thử nghiệm với việc truy cập cấu trúc chủ đề, điều này mang lại cho tôi và 'bao gồm cả thời gian, vòng lặp và truy cập thực tế.
Sự khác biệt giữa thời gian 'trần' và 'thời gian không có phí' cho tôi một dấu hiệu về thời gian 'truy cập cấu trúc'.
Nhưng làm thế nào chính xác là thời gian này? Trong các cửa sổ kiểm tra sẽ làm một số thời gian cắt cho shure. Tôi không có thông tin về việc cắt thời gian nhưng tôi cho rằng nó được phân phối đều trong quá trình thử nghiệm và theo thứ tự hàng chục ms có nghĩa là độ chính xác cho thời gian phải theo thứ tự +/- 100 msec hoặc hơn. Một ước tính sơ bộ? Dù sao một nguồn của một lỗi mearure có hệ thống.
Ngoài ra, các thử nghiệm đã được thực hiện trong chế độ 'Gỡ lỗi' mà không tối ưu hóa. Nếu không, trình biên dịch có thể thay đổi mã kiểm tra thực tế.
Vì vậy, tôi nhận được hai kết quả, một cho hằng số, được đánh dấu '(c)' và một cho truy cập được đánh dấu '(n)' và sự khác biệt 'dt' cho tôi biết thời gian truy cập thực tế mất bao lâu.
Và đây là kết quả:
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
Với ước tính tốt hơn về các lỗi thời gian (làm thế nào để loại bỏ lỗi đo lường hệ thống do cắt thời gian?) Có thể nói nhiều hơn về kết quả.
Có vẻ như List / foreach có quyền truy cập nhanh nhất nhưng chi phí đang giết chết nó.
Sự khác biệt giữa List / for và List / foreach là stange. Có thể một số tiền mặt có liên quan?
Hơn nữa, để truy cập vào một mảng, không quan trọng nếu bạn sử dụng for
vòng lặp hoặc foreach
vòng lặp. Kết quả thời gian và độ chính xác của nó làm cho kết quả 'có thể so sánh'.
Sử dụng từ điển là chậm nhất, tôi chỉ xem xét nó bởi vì ở phía bên trái (bộ chỉ mục) tôi có một danh sách các số nguyên thưa thớt và không phải là một phạm vi như được sử dụng trong các bài kiểm tra này.
Đây là mã kiểm tra sửa đổi.
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);