Tôi cần lưu trữ một tập hợp các phần tử. Những gì tôi cần chức năng đểLấy phần tử ngẫu nhiên từ C# HashSet nhanh chóng
- remove (duy nhất) các yếu tố và
- add (bộ) các yếu tố và
- mỗi đối tượng chỉ phải ở trong các thiết lập một lần và
- có được một yếu tố ngẫu nhiên từ thiết
tôi đã chọn HashSet (C#) vì nó thể thao nhanh phương pháp để loại bỏ các yếu tố (hashSet.remove (element)), thêm bộ (hashSet.UnionWith (anotherHashSet)) và bản chất của một HashSet đảm bảo rằng không có bản sao, vì vậy yêu cầu 1 đến 3 được thực hiện.
Cách duy nhất tôi tìm thấy để có được một yếu tố ngẫu nhiên là
Object object = hashSet.ElementAt(rnd.Next(hashSet.Count));
Nhưng điều này là rất chậm, kể từ khi tôi gọi nó là một lần cho mỗi điểm ảnh của bản đồ của tôi (tạo ra một điền lũ ngẫu nhiên từ nhiều điểm khởi đầu; bản đồ hóa 500x500 tại thời điểm này nhưng tôi muốn đi lớn hơn) và hashset giữ khá nhiều mục. (Một thử nghiệm nhanh cho thấy nó thổi lên đến 5752 mục trước khi thu hẹp lại.)
Hồ sơ (lấy mẫu CPU) cho tôi biết các cuộc gọi ElementAt của tôi chiếm hơn 50%.
Tôi nhận thấy hoạt động 500x500 trên băm lớn không phải là nhiệm vụ dễ dàng, nhưng các thao tác khác (Remove và UnionWith) được gọi thường xuyên là ElementAt, vì vậy vấn đề chính dường như là hoạt động chứ không phải số lượng cuộc gọi.
Tôi mơ hồ hiểu tại sao nhận một yếu tố nhất định từ HashSet là rất tốn kém (khi so sánh với nó từ danh sách hoặc cấu trúc dữ liệu được sắp xếp khác, nhưng tôi chỉ muốn chọn ngẫu nhiên. không có cách nào xung quanh nó? có một cấu trúc dữ liệu tốt hơn cho mục đích của tôi?
Thay đổi tất cả mọi thứ để Lists không giúp vì bây giờ các phương pháp khác trở nên tắc nghẽn và phải mất nhiều thời gian hơn.
đúc HashSet đến một mảng và chọn phần tử ngẫu nhiên của tôi từ đó dự kiến sẽ không giúp đỡ bởi vì trong khi chọn một phần tử ngẫu nhiên từ một mảng là nhanh chóng, đúc hashset vào mảng ở vị trí đầu tiên mất nhiều thời gian hơn chạy hashSet.ElementAt một mình.
Nếu bạn muốn hiểu rõ hơn về những gì tôi đang cố gắng để làm: A link to my question and the answer.
Bạn đang xóa gì? Nó chỉ là nguyên tố ngẫu nhiên, hay là tùy ý? – spender
Tại sao không làm tất cả việc thêm và xóa của bạn với HashSet, sau đó trước khi bạn muốn thực hiện lấy pixel ngẫu nhiên, chỉ cần chuyển đổi thành Danh sách một lần? Sử dụng danh sách đó , sau đó vứt đi sau đó. Trừ khi bạn cần phải thêm, loại bỏ và nhận được các yếu tố ngẫu nhiên cùng một lúc ... –
Baldrick
@spender Tôi loại bỏ các yếu tố ngẫu nhiên tìm thấy chỉ –