2013-05-08 20 views
14

Tôi muốn biết trong trường hợp nào các cấu trúc dữ liệu là tối ưu để sử dụng kiểm tra "chứa" hoặc "tồn tại".SCALA: Cấu trúc dữ liệu nào tối ưu trong đó siutations khi sử dụng ".contains()" hoặc ".exists()"?

Tôi hỏi vì tôi đến từ một nền Python và sáng sử dụng để sử dụng các biểu thức if x in something: cho mọi thứ. Ví dụ, trong đó biểu thức được đánh giá là nhanh nhất:

val m = Map(1 -> 1, 2 -> 2, 3 -> 3, 4 -> 4) 
              //> m : scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 2 -> 2, 3 -> 3, 4 
              //| -> 4) 
val l = List(1,2,3,4)      //> l : List[Int] = List(1, 2, 3, 4) 
val v = Vector(1,2,3,4)     //> v : scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4) 

m.exists(_._1 == 3)      //> res0: Boolean = true 
m.contains(3)        //> res1: Boolean = true 
l.exists(_ == 3)       //> res2: Boolean = true 
l.contains(3)        //> res3: Boolean = true 
v.exists(_ == 3)       //> res4: Boolean = true 
v.contains(3)        //> res5: Boolean = true 

trực giác, tôi sẽ giả định rằng vectơ nên là nhanh nhất để kiểm tra ngẫu nhiên, và danh sách sẽ là nhanh nhất nếu ai biết rằng giá trị kiểm tra là vào đầu những và có rất nhiều dữ liệu. Tuy nhiên, một xác nhận hoặc sửa chữa sẽ được chào đón nhiều nhất. Ngoài ra, vui lòng mở rộng sang các cấu trúc dữ liệu khác.

Lưu ý: Vui lòng cho tôi biết nếu bạn cảm thấy câu hỏi này quá mơ hồ vì tôi không chắc tôi đang nói đúng cách.

+1

FYI http://www.scala-lang.org/docu/files/collections-api/collections_40.html –

+0

Trong Python, giống như mọi ngôn ngữ khác, loại dữ liệu trừu tượng được lựa chọn khi bạn chủ yếu cần kiểm tra thành viên là một ** tập **, không phải là một chuỗi hoặc ánh xạ. – delnan

+0

Kiểm tra một phần tử cụ thể là ** không ** kiểm tra ngẫu nhiên, nó ngắn hơn quét toàn bộ vectơ/danh sách/mảng: * lấy phần tử đầu tiên, so sánh, nếu không bằng, mất giây, so sánh, ... *. Ở phía bên kia, 'contains' trên tập hợp và bản đồ có nghĩa là không đổi (không giống như tồn tại, trước tiên phải áp dụng một số biến vị ngữ nào đó và vì vậy, tôi nghĩ là tuyến tính) –

Trả lời

14

SetMap (với triển khai bảng băm mặc định) là nhanh nhất tại contains vì chúng tính toán giá trị băm và chuyển đến đúng vị trí ngay lập tức. Ví dụ: nếu bạn muốn tìm một chuỗi tùy ý trong danh sách một nghìn, contains trên tập hợp nhanh hơn 100x contains trên List hoặc Vector hoặc Array.

Với exists, bạn thực sự chỉ quan tâm đến bộ sưu tập nhanh như thế nào để đi ngang - bạn phải duyệt mọi thứ. Ở đó, List thường là nhà vô địch (trừ khi bạn muốn đi qua một mảng bằng tay), nhưng chỉ Set và thường đặc biệt xấu (ví dụ: exists trên List là ~ 8x nhanh hơn trên Set khi mỗi có 1000 phần tử). Những người khác nằm trong khoảng 2.5x của List (thường là 1.5x, nhưng Vector có cấu trúc cây bên dưới không phải là tất cả nhanh để lướt qua).

+0

Điều này sẽ không liên quan đến việc sử dụng nhiều nhất trường hợp, nhưng nếu bạn sẵn sàng cung cấp cho cấu trúc vị ngữ 'tồn tại' của bạn nhiều hơn một hàm mờ, nó sẽ có thể thực hiện nó hiệu quả hơn. Nếu bạn định nghĩa một AST đơn giản cho các quan hệ có thể, thì các cấu trúc dựa trên băm sẽ tốt ở các vị từ bình đẳng, trong khi các cấu trúc được sắp xếp ('TreeMap',' IntMap' với gotchas) sẽ tốt ở các vị từ bình đẳng _and_ sắp đặt các vị từ. Các thử nghiệm có thể tốt ở các vị từ kết hợp tiền tố và bạn có thể nhận được các DAWG tùy ý phức tạp và như vậy. Thêm các biến liên quan trong DSL vị ngữ của bạn và nó sẽ thậm chí còn hấp dẫn hơn! –

+0

@MyseriousDan - 'exist' là tên của bài kiểm tra không có cấu trúc trong thư viện bộ sưu tập. Tất nhiên có những biến đổi thành 'contains' cho sự bình đẳng và cái gì đó tương đương với' dải ô' cho cây.Nhưng đó không phải là 'tồn tại', đó là cái gì khác. (Ý bạn là để trả lời gzm0, người tuyên bố rằng không có gì nhanh hơn O (n) cho 'tồn tại'? Câu trả lời của bạn sẽ có ý nghĩa hơn trong ngữ cảnh đó.) –

+0

Err, vâng, xin lỗi :) nhưng tôi biết rằng' tồn tại' là một phương thức API: P Tôi chỉ nói rằng nếu chúng ta sẵn sàng phá vỡ mô hình hàm mờ, chúng ta có thể làm tốt hơn (nhưng vẫn có cách nhúng các hàm tùy ý với một chuyển đổi ngầm, để mọi người có thể giả vờ giao diện thông minh hơn không tồn tại) –

1

Nếu bạn muốn sử dụng rộng rãi contains, bạn nên sử dụng Set (hoặc Map).

AFAIK không có cơ sở hạ tầng thực hiện hiệu quả (tức là nhanh hơn O (n)) exists kể từ khi đóng cửa bạn chuyển vào có thể thậm chí không liên quan đến các yếu tố bên trong.

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