2012-03-05 26 views
7

Ngoài sự tò mò, tôi muốn kiểm tra số lượng bọ ve để so sánh một GenericList với ArrayList.Tại sao một Danh sách đơn giản <T> dường như chậm hơn một ArrayList?

Và đối với mã bên dưới khi tôi kiểm tra đồng hồ bấm giờ, ArrayList có vẻ nhanh hơn.

Tôi có làm điều gì đó sai hoặc có giải thích cho điều này không? (Tôi tin Danh sách sto được nhanh hơn nhiều)

Tesing Mã và đầu ra dưới đây:

private static void ArrayListVsGenericList() 
{ 
    // Measure for ArrayList 
    Stopwatch w0 = new Stopwatch(); 
    w0.Start(); 

    ArrayList aList = new ArrayList(); 

    for (int i = 0; i < 1001; i++) 
    { 
     Point p = new Point(); 
     p.X = p.Y = i; 

     aList.Add(p); 
    } 

    foreach (Point point in aList) 
    { 
     int v0 = ((Point) aList[8]).X; //unboxing 
    } 


    w0.Stop(); 

    // Measure for Generic List<Point> 
    Stopwatch w1 = new Stopwatch(); 
    w1.Start(); 

    List<Point> list = new List<Point>(); 

    for (int i = 0; i < 1001; i++) 
    { 
     Point p = new Point(); 
     p.X = p.Y = i; 

     list.Add(p); 
    } 


    foreach (var point in list) 
    { 
     int v1 = list[8].X; 
    } 

    w1.Stop(); 

    Console.WriteLine("Watch 0 : " + w0.ElapsedTicks); 
    Console.WriteLine("Watch 1 : " + w1.ElapsedTicks); 
    Console.WriteLine("Watch 0 > Watch 1 : " + (w0.ElapsedTicks > w1.ElapsedTicks)); 
} 

enter image description here

+0

Tôi không nghĩ rằng thử nghiệm này là đáng tin cậy. Trình tự thực thi mã là quan trọng, để bắt đầu. Việc thêm vào Danh sách thứ hai có thể bị phân bổ trước đó. Ngoài ra 1000 yếu tố là một tập hợp nhỏ. Bạn chắc chắn nên tách các điền và nhận được của hai loại danh sách trong hai chương trình khác nhau và sau đó kiểm tra chúng bằng cách sử dụng một hồ sơ, không đồng hồ bấm giờ. – vulkanino

+0

Làm thế nào để nó trông khi sử dụng 'int' thay vì 'Point's? Khi kiểm tra danh sách chung trước? –

+0

Vâng, khi tôi tăng số phần tử lên 1000001 generics thì nhanh hơn. Nhưng điều này có nghĩa là Generics không thể được coi là NHANH CHÓNG nhất khi làm việc trên các bộ phần tử nhỏ? – pencilCake

Trả lời

7

Thay đổi chương trình thử nghiệm của bạn để chạy phương pháp của bạn ít nhất hai lần và bỏ qua chạy đầu tiên . Kết quả là do việc tạo mã và nhái cho loại bê tông List<Point>.

Trên máy tính của tôi điều này dẫn đến kết quả như sau:

Watch 0 : 154 
    Watch 1 : 74 
    Watch 0 > Watch 1 : True 

Đó là khá nhiều những gì người ta mong đợi.

+0

Bạn đang PHẢI! Trong lần chạy thứ hai, nó nhanh hơn rất nhiều ngay cả đối với một tập hợp các phần tử nhỏ. (Vì vậy, trong trường hợp này Nếu tôi chạy NGEN.exe; Tôi sẽ đảm bảo chạy đầu tiên để được nhanh chóng cũng như cho danh sách chung, tôi giả định) – pencilCake

5

Bạn đã không loại bỏ các hiệu ứng thực thi đầu tiên như JIT. Generics cần phải được biên dịch một lần cho mỗi đối số kiểu giá trị.

ArrayList đã được biên dịch trước bằng ngen.

List<T> chỉ được biên dịch trước cho các kiểu tham số nhất định (tôi đọc rằng các thư viện lõi khởi tạo một số generics quan trọng nhất cho các đối số chung, như đối tượng, bool, int, ...), nếu có. Vì vậy, nó sẽ phải chịu một chi phí một lần.

Bạn cũng nên lưu ý rằng hầu hết chi phí hiệu suất của ArrayList là gián tiếp: Quyền anh đặt áp lực cao hơn lên GC và sử dụng nhiều bộ nhớ hơn. Nhưng thử nghiệm của bạn sẽ không đo lường điều đó. Chi phí sản xuất thêm rác cũng phụ thuộc vào số lượng vật thể khác tồn tại, và tuổi thọ của vật thể.

Khi bạn viết kiểm tra, bạn nên thực thi tất cả mã một lần trước khi thử nghiệm thực tế hoặc sử dụng quá nhiều lần lặp lại mà chi phí một lần không đáng kể. Bạn cũng nên sử dụng bản phát hành và chạy mà không cần trình gỡ lỗi đính kèm.

Các vấn đề liên quan