2016-04-29 26 views
7

Tôi nhận thấy rằng các mảng hoạt động nhanh hơn nhiều so với các danh sách liên kết của Haxe (ít nhất là trên cpp). Kết quả tôi nhận được như sau.Tại sao sử dụng Danh sách, khi Mảng nhanh hơn?

Main.hx:40: With 1 items, Array is 14% faster than List. 
Main.hx:40: With 5 items, Array is 58% faster than List. 
Main.hx:40: With 10 items, Array is 59% faster than List. 
Main.hx:40: With 100 items, Array is 54% faster than List. 
Main.hx:40: With 1000 items, Array is 56% faster than List. 
Main.hx:40: With 10000 items, Array is 55% faster than List. 
Main.hx:40: With 100000 items, Array is 52% faster than List. 

Điều này khiến tôi trở nên rực rỡ. Làm thế nào có thể Array nhanh như vậy mặc dù nó phải sao chép các mục liên tục? Và tại sao thậm chí sử dụng Danh sách sau đó?

package tests; 

import haxe.Timer; 

class Main 
{ 

    static function main() 
    { 
     var arr:Array<Int> = new Array(); 
     var list:List<Int> = new List(); 
     var result = new List(); 

     for (items in [1, 5, 10, 100, 1000, 10000, 100000]) { 
      var listtime = timeit(10000, function() { 
       for (i in 0...items) 
        list.add(i); 
       for (x in list) 
        result.add(x); 
       result.clear(); 
       list = new List(); 
      }); 

      var arrtime = timeit(10000, function() { 
       for (i in 0...items) 
        arr.push(i); 
       for (x in arr) 
        result.add(x); 
       result.clear(); 
       arr = new Array(); 
      }); 

      if (arrtime < listtime) 
       trace('With $items items, Array is ${Std.int((1-arrtime/listtime)*100)}% faster than List.'); 
      else 
       trace('With $items items, List is ${Std.int((1-listtime/arrtime)*100)}% faster than Array.'); 
     } 
    } 

    static public function timeit<T>(times:Int, f:Void -> T):Float { 
     var start = Timer.stamp(); 
     for (i in 0...times) { 
      f(); 
     } 
     var time = Timer.stamp() - start; 
     return time; 
    } 

} 
+0

[Địa phương tham chiếu] (https://en.wikipedia.org/wiki/Locality_of_reference) – Drop

+0

Ngoài ra, nếu bạn xem danh sách được triển khai như thế nào trong haxe, chúng tạo một loạt các mảng nhỏ vì bất kỳ lý do gì và thêm 2 các phần tử cho mỗi phần tử và tự nhiên sẽ chậm hơn so với việc thêm vào một mảng. – MSGhero

Trả lời

6

Làm thế nào mà mảng có thể nhanh quá dù phải sao chép các mục liên tục?

Mảng xử lý tuyến tính nhanh hơn vì nội dung mảng được lưu trữ liên tục trong bộ nhớ. Khi bạn truy cập bộ nhớ tuyến tính, nhiều đối tượng sẽ được tải xuống bộ nhớ cache của bộ xử lý cùng một lúc. Các nút danh sách được liên kết, mặt khác nằm rải rác trong toàn bộ bộ nhớ, do đó, xử lý chúng một cách tuyến tính sẽ dẫn đến nhiều thừa số hơn trong bộ nhớ chính. Đọc bộ nhớ cache nhanh hơn rất nhiều so với việc đọc bộ nhớ chính.

Và tại sao lại sử dụng Danh sách?

Một lý do chính để sử dụng danh sách được liên kết là chèn phần tử mới hoặc xóa các phần tử hiện có, không làm mất hiệu lực tài liệu tham khảo (bao gồm vòng lặp và con trỏ) cho các phần tử khác trong danh sách được liên kết. Một mảng không thể có bảo đảm như vậy.

+0

Chọn mục này là được chấp nhận, vì nó có nhiều thông tin hơn. – seequ

4

Tại sao sử dụng Danh sách, khi mảng nhanh hơn?

Nhanh hơn cho những gì? Danh sách được liên kết thường nhanh hơn rất nhiều khi nói đến việc chèn các phần tử giữa các phần tử khác hoặc xóa các phần tử ở giữa danh sách. Với một mảng (ít nhất, một mảng kiểu C) chèn hoặc xóa tại vị trí i yêu cầu di chuyển mọi phần tử sau i. Với danh sách được liên kết, bạn chỉ cần thay đổi một vài gợi ý.

Hãy thử lại lần nữa, nhưng thay vì đẩy các phần tử vào cuối danh sách, hãy chèn chúng vào đầu.

+1

Hmm, tôi hiểu rồi. Không biết tại sao tôi không nghĩ về điều đó. – seequ

+0

Ví dụ "chèn lúc bắt đầu" của bạn, 'std :: deque' sẽ nhanh hơn danh sách, vì vậy tôi không nghĩ rằng việc xác minh việc sử dụng danh sách sẽ rất tốt. – user2079303

+0

@ user2079303 Bạn bỏ lỡ điểm, đó là cấu trúc dữ liệu khác nhau có điểm mạnh và điểm yếu khác nhau. Tôi đã nói * chèn chúng vào đầu * bởi vì trong bối cảnh của bài kiểm tra của OP, đó là một thay đổi dễ dàng cho thấy một trường hợp danh sách nhanh hơn mảng. – Caleb

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