8

Tôi đang viết một hệ thống nhỏ trong Java, trong đó tôi trích xuất tính năng n-gram từ tập tin văn bản và sau đó cần phải thực hiện quá trình lựa chọn Feature để chọn hầu hết các tính năng discriminators.Thực hành tốt nhất để giữ danh sách lớn các dữ liệu trong Java

Quá trình khai thác tính năng cho một tập tin duy nhất quay trở lại một bản đồ, trong đó có cho mỗi tính năng độc đáo, lần xuất hiện của nó trong file. Tôi hợp nhất tất cả các bản đồ của tệp (Bản đồ) vào một Bản đồ có chứa Tần suất tài liệu (DF) của tất cả các tính năng độc đáo được trích xuất từ ​​tất cả các tệp. Bản đồ hợp nhất có thể chứa trên 10.000.000 mục nhập.

Hiện tại quá trình trích xuất tính năng đang hoạt động tốt và tôi muốn thực hiện Lựa chọn tính năng mà tôi cần triển khai Thông tin tăng hoặc tỷ lệ tăng. Tôi sẽ phải sắp xếp Bản đồ đầu tiên, thực hiện tính toán và lưu kết quả để cuối cùng có được danh sách (đối với mỗi đối tượng, điểm Lựa chọn tính năng)

Câu hỏi của tôi là: Thực hành tốt nhất và tốt nhất là gì cấu trúc dữ liệu để giữ số lượng lớn dữ liệu này (~ 10M) và thực hiện tính toán?

+0

Hãy xem HashMap. – Hungry

Trả lời

1

Trực giác của tôi là bạn có thể lấy cảm hứng từ mô hình MapReduce ban đầu và phân chia vấn đề của bạn thành một số nhỏ hơn nhưng tương tự và sau đó tổng hợp các kết quả này để đạt được giải pháp hoàn chỉnh.

Nếu bạn giải quyết một sự cố nhỏ hơn tại một thời điểm (ví dụ: đoạn tệp), điều này sẽ đảm bảo cho bạn một hình phạt tiêu thụ không gian bị ràng buộc bởi các yêu cầu về không gian cho trường hợp đơn lẻ này.

Cách tiếp cận này để xử lý tệp lười sẽ làm việc bất biến của cấu trúc dữ liệu bạn chọn.

1

Bạn có thể sử dụng hệ thống bộ nhớ đệm, kiểm tra MapDB nó rất hiệu quả và có triển khai bản đồ cây (để bạn có thể yêu cầu dữ liệu của mình mà không cần bất kỳ nỗ lực nào). Ngoài ra, nó cung cấp các kho dữ liệu để lưu dữ liệu của bạn vào đĩa khi nó không thể được giữ trên bộ nhớ.

// here a sample that uses the off-heap memory to back the map 
Map<String, String> map = DBMaker.newMemoryDirectDB().make().getTreeMap("words"); 

//put some stuff into map 
map.put("aa", "bb"); 
map.put("cc", "dd"); 
5

Đây là một câu hỏi rất rộng, vì vậy câu trả lời là sẽ rộng quá. Các giải pháp phụ thuộc vào (ít nhất) ba điều này:

  1. Kích thước của các mục của bạn

Lưu trữ 10.000.000 số nguyên sẽ cần khoảng 40MiB bộ nhớ, trong khi lưu trữ 10.000.000 x 1KiB hồ sơ sẽ đòi hỏi nhiều hơn 9GiB . Đây là hai vấn đề khác nhau. Mười triệu số nguyên là tầm thường để lưu trữ trong bộ nhớ trong bất kỳ bộ sưu tập Java cổ phiếu nào, trong khi vẫn giữ 9GiB trong bộ nhớ sẽ buộc bạn phải tinh chỉnh và điều chỉnh Java Heap và bộ thu gom rác. Nếu các mục nhập thậm chí còn lớn hơn, hãy nói 1MiB, sau đó bạn có thể quên hoàn toàn bộ nhớ trong bộ nhớ. Thay vào đó, bạn sẽ cần phải tập trung vào việc tìm kiếm một cấu trúc dữ liệu được sao lưu trên đĩa tốt, có thể là một cơ sở dữ liệu.

  1. Các phần cứng bạn đang sử dụng

Lưu trữ mười triệu hồ sơ 1KiB trên một máy với 8 GiB của ram là không giống như lưu trữ chúng trên máy chủ với 128GiB . Những điều mà khá nhiều không thể với máy cũ là tầm thường với sau này.

  1. Các loại tính toán (s) bạn muốn làm

Bạn đã đề cập đến sắp xếp, vì vậy những thứ như TreeMap hoặc có thể PriorityQueue đến tâm. Nhưng liệu tính toán chuyên sâu nhất? Và chìa khóa bạn đang sử dụng để sắp xếp chúng là gì? Bạn có kế hoạch định vị (nhận) các thực thể dựa trên các thuộc tính khác không phải là chìa khóa không? Nếu vậy, yêu cầu lập kế hoạch riêng. Nếu không, bạn cần lặp lại tất cả mười triệu mục nhập.

Tính toán của bạn có chạy trong một chuỗi hoặc nhiều chuỗi không? Nếu bạn có thể có sửa đổi đồng thời dữ liệu của mình, điều đó yêu cầu giải pháp riêng. Các cấu trúc dữ liệu như TreeMap và PriorityQueue sẽ phải được khóa hoặc thay thế bằng các cấu trúc đồng thời như ConcurrentLinkedHashMap hoặc ConcurrentSkipListMap.

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