Sắp xếp các thuật toán hoạt động trên lượng dữ liệu lớn


12

Tôi đang tìm kiếm các thuật toán sắp xếp có thể hoạt động trên một lượng lớn dữ liệu, tức là có thể hoạt động ngay cả khi toàn bộ tập dữ liệu không thể được giữ trong bộ nhớ chính cùng một lúc.

Ứng cử viên duy nhất mà tôi tìm thấy cho đến nay là sắp xếp hợp nhất: bạn có thể triển khai thuật toán theo cách nó quét tập dữ liệu của bạn tại mỗi hợp nhất mà không cần giữ tất cả dữ liệu trong bộ nhớ chính cùng một lúc. Sự thay đổi của loại hợp nhất tôi có trong tâm trí được mô tả trong bài viết này trong phần Sử dụng với các ổ đĩa băng .

Tôi nghĩ rằng đây là một giải pháp tốt (với độ phức tạp O (nx log (n)) nhưng tôi tò mò muốn biết liệu có các thuật toán sắp xếp khác (có thể nhanh hơn) có thể hoạt động trên các tập dữ liệu lớn không phù hợp với bộ nhớ chính hay không.

BIÊN TẬP

Dưới đây là một số chi tiết, theo yêu cầu của câu trả lời:

  • Dữ liệu cần được sắp xếp theo định kỳ, ví dụ một lần trong một tháng. Tôi không cần phải chèn một vài bản ghi và sắp xếp dữ liệu tăng dần.
  • Tệp văn bản ví dụ của tôi là khoảng 1 GB văn bản UTF-8, nhưng tôi muốn giải quyết vấn đề nói chung, ngay cả khi tệp đó là 20 GB.
  • Nó không có trong cơ sở dữ liệu và do các ràng buộc khác, nó không thể.
  • Dữ liệu được người khác đổ vào dưới dạng tệp văn bản, tôi có mã riêng để đọc tệp văn bản này.
  • Định dạng của dữ liệu là một tệp văn bản: các ký tự dòng mới là dấu phân cách bản ghi.

Một cải tiến có thể có trong đầu tôi là chia tệp thành các tệp đủ nhỏ để sắp xếp trong bộ nhớ và cuối cùng hợp nhất tất cả các tệp này bằng thuật toán tôi đã mô tả ở trên.


1
Những loại dữ liệu? Các bộ dữ liệu khác nhau có thể có nghĩa là các thuật toán khác nhau phù hợp nhất với mục đích của bạn.
tên của

Nó là một tệp văn bản và tôi phải sắp xếp các dòng. Các dòng không có độ dài cố định nhưng độ dài không thay đổi quá nhiều (khoảng 50 ký tự cho mỗi bản ghi).
Giorgio

3
Tôi không biết môi trường của bạn hoặc các ràng buộc của bạn, nhưng tôi sẽ sử dụng cơ sở dữ liệu để sắp xếp bất cứ khi nào có thể. Điều này là do nó gần như không bị lỗi 100% và sẽ hiệu quả hơn nhiều so với mã của tôi.
NoChance

Tôi đang làm việc trên Linux / Java. Tôi đã thực hiện sắp xếp hợp nhất và nó dường như hoạt động khá trơn tru. Sắp xếp vài triệu dòng mất khá nhiều thời gian nhưng tôi chỉ cần thực hiện việc này một lần trong một thời gian.
Giorgio

@Giorgio, thật tốt khi bạn đã thực hiện một thuật toán như vậy. Đối với công việc sản xuất, tôi vẫn đề nghị bạn sử dụng cơ sở dữ liệu. Không chỉ về tốc độ mà còn về độ tin cậy và dễ bảo trì.
NoChance

Câu trả lời:


13

Tài liệu tham khảo chính tắc về sắp xếp và tìm kiếm là Knuth, Vol. 3 . Bắt đầu từ đó

Cuốn sách ban đầu được viết lại khi máy tính nhỏ hơn và chậm hơn rất nhiều so với hiện tại, điều này khiến cho các kỹ thuật sắp xếp ngoài bộ nhớ trở nên quan trọng hơn so với chúng ngày nay.


2
Cảm ơn đã tham khảo: Tôi gần như chắc chắn rằng tôi sẽ tìm thấy tài liệu thú vị trong cuốn sách của Knuth. Tôi không chắc chắn rằng các kỹ thuật sắp xếp ngoài bộ nhớ ngày nay không liên quan. Có thể không phải cho các nhiệm vụ thông thường, hàng ngày, nhưng tôi có thể tưởng tượng rằng vẫn còn nhiều tình huống trong đó các tập dữ liệu rất lớn cần được xử lý.
Giorgio

Các thuật toán của Knuth luôn hữu ích. Ví dụ, sắp xếp hợp nhất với bộ đệm heap-sort có thể rất hiệu quả và RẤT dễ thực hiện.
Sulthan

4
Không phải là một câu trả lời rất hữu ích vì tài liệu được giới thiệu không miễn phí. Đối với OP, tôi đề nghị googling cho một câu trả lời. Bạn không cần phải bỏ ra 50 đô la để có được một cuốn sách khi loại thông tin này bạn có thể tìm thấy bằng cách tìm kiếm trên web. Tất nhiên, bạn có thể có thể tải xuống miễn phí từ ( ahem ) một số trang web nhất định. Hầu như không xứng đáng với một câu trả lời được chấp nhận.
Thomas Eding

1
@ThomasEding, có những thứ gọi là "thư viện", chứa số lượng lớn các thiết bị lưu trữ và truy xuất thông tin lỗi thời này được gọi là "sách". "Thư viện" cung cấp "sách" cho VAY MIỄN PHÍ. Nếu "thư viện" cụ thể của bạn không có "cuốn sách" cụ thể mà bạn tìm kiếm, họ cũng cung cấp dịch vụ MIỄN PHÍ có tên là "mượn liên thư viện", cho phép "thư viện" mượn "sách" từ "thư viện" khác, để họ có thể cho bạn mượn
John R. Strohm

6

Hợp nhất R-Way bên ngoài như trong sortlệnh UNIX là một lựa chọn tốt. Từ công thức của bạn, tôi không chắc đó có phải là thuật toán mà bạn muốn nói với "hợp nhất sắp xếp" hay không và nếu bạn không biết, hãy xem.


Cảm ơn. Hợp nhất R-Way bên ngoài có vẻ khác với những gì tôi đã nghĩ. Thú vị đọc.
Giorgio

4

Không có chi tiết cụ thể hơn "Sắp xếp hợp nhất" có lẽ là câu trả lời tốt nhất bạn sẽ nhận được, tuy nhiên bạn có thể thực hiện một cái gì đó thông minh hơn nhiều tùy thuộc vào yêu cầu của bạn.

Chẳng hạn, bạn có thể chỉ cần tạo một chỉ mục trong bộ nhớ của tệp sau đó sao chép tất cả các giá trị cùng một lúc, lưu vào vị trí của các giá trị khóa khác nhau không? Liệu 1/2 có phù hợp với bộ nhớ cùng một lúc hay 1/1000000 không? Nếu đó là cái thứ hai thì bạn có thể không vừa với một chỉ mục trong bộ nhớ, nếu là cái thứ nhất thì bạn có thể sắp xếp cả hai nửa hiệu quả hơn sau đó hợp nhất chúng lại với nhau trong bước cuối cùng.

Chết tiệt, vì bạn đã không chỉ định nên có thể dữ liệu của bạn là tất cả trong cơ sở dữ liệu, nếu vậy bạn chỉ cần tạo một bảng chỉ mục và gọi nó là tốt (tôi đoán đây không phải là trường hợp, nhưng chỉ ra rằng tình huống của bạn là rất quan trọng để giải quyết một vấn đề phức tạp như thế này).

Nếu bạn muốn thực hiện nó chỉ một lần và đang tìm kiếm một bản hack rất nhanh, có vẻ như loại hợp nhất bên ngoài đó sẽ là một khởi đầu tốt nếu bạn đang chạy unix (vì rõ ràng nó được tích hợp sẵn)

Nếu bạn phải giữ nó theo thứ tự và luôn luôn thêm một bản ghi thì một loại chèn sẽ là cần thiết (Thêm một bản ghi vào dữ liệu được sắp xếp luôn luôn là một loại chèn).

Bạn có thể kiểm soát mã "Đọc" dữ liệu không? Nếu vậy thì nhiều hình thức lập chỉ mục (thay vì sắp xếp bằng cách di chuyển dữ liệu trên đĩa) sẽ giúp rất nhiều (thực sự sẽ là một yêu cầu tuyệt đối).

Vì thế:

  • Tại chỗ hoặc nhiều tập tin?
  • Một lần, định kỳ hoặc giữ nó sắp xếp mọi lúc?
  • Lớn hơn bao nhiêu bộ nhớ (Có bao nhiêu bộ nhớ để tải qua toàn bộ tập dữ liệu)?
  • Có phải trong một cơ sở dữ liệu? Có thể được không?
  • Bạn có kiểm soát mã đọc dữ liệu hoặc người khác sẽ trực tiếp bán tệp không?
  • Định dạng tập tin? (Văn bản? Bản ghi cố định?)
  • Có trường hợp đặc biệt nào khác mà tôi không hỏi về không?

Cảm ơn câu trả lời. Bạn có ý nghĩa gì bởi "Tại chỗ hoặc nhiều bản ghi"?
Giorgio

Xin lỗi, nên đọc bằng chứng câu trả lời của tôi - ý tôi là nhiều tập tin. Tại chỗ khá nhiều ngụ ý kích thước bản ghi cố định và lập chỉ mục tại điểm mà bạn có thể muốn có một cơ sở dữ liệu.
Bill K

Không, nó không đúng chỗ: hồ sơ không có kích thước cố định. Tôi sử dụng bốn tệp tạm thời để thực hiện hiện tại của tôi.
Giorgio

Bạn có thể diễn giải đầu ra bằng mã hoặc nó phải ở một định dạng cụ thể (tệp văn bản phẳng?) Bao lâu thì cần phải sắp xếp - mỗi khi một cái gì đó được thêm vào hoặc chỉ thỉnh thoảng? Khi một cái gì đó được thêm vào, nó chỉ được thêm vào cuối hoặc bạn có thể viết mã thêm nó không?
Bill K

Mỗi dòng có thể được phân tích thành một bản ghi (tệp là tệp CSV) nhưng hầu hết các trường là văn bản. Nó cần được sắp xếp một lần trong một thời gian (ví dụ mỗi tháng) và mất khoảng 1 giờ để sắp xếp với việc thực hiện hiện tại của tôi. Để chèn một dòng tôi có thể viết mã chèn dòng đó vào đúng chỗ: với mã tôi có cho đến nay, tôi sẽ mất 20 phút để viết một công cụ như vậy.
Giorgio

3

Nếu bạn thực sự muốn một giải pháp có thể mở rộng, bạn nên xem TeraSort, cách thực hiện sắp xếp tiêu chuẩn với map-less; biết thêm chi tiết về StackOverflow .


1
+1: Liên kết thú vị. Không hợp nhất sắp xếp một ví dụ về bản đồ / thu nhỏ, trong đó bản đồ tương ứng với việc sắp xếp danh sách phụ và giảm tương ứng với việc hợp nhất?
Giorgio

Nó có thể được nhìn thấy như vậy, nhưng bạn có thể sử dụng Hadoop để làm điều này cho bạn thay vì tự viết nó.
m3th0dman

1

Bạn có thể quan tâm đến một loại xô . Hiệu suất trường hợp trung bình là thời gian tuyến tính.

= O (n + d) n: số phần tử và d = chiều dài của số lớn nhất nếu bạn có trực giác về dữ liệu của mình tức là. Nếu bạn biết bao nhiêu chữ số là số lớn nhất của bạn. Vì vậy, nếu bạn có 2 triệu số có 6 chữ số => 0 (n) thì tuyến tính.


0

Sử dụng thuật toán sắp xếp hợp nhất bên ngoài (nếu dữ liệu của bạn là continuos) hoặc sắp xếp nhóm với sắp xếp đếm như là một triển khai sắp xếp cho các nhóm (nếu dữ liệu của bạn rời rạc và phân bố đồng đều).

Có lẽ cách tiếp cận tốt nhất là xây dựng tệp chỉ mục / ánh xạ của riêng bạn nếu mức tăng nhỏ.

  1. Bằng cách nào đó đặt hàng "cơ sở dữ liệu" của bạn
  2. Gán một số nguyên cho mọi mục nhập (1, 2, 3, 4, ..., n) (tốt hơn: sử dụng một số chỉ mục thưa thớt)
  3. Khi thêm một số gia, chỉ cần tìm một khoảng trống trong đó số bên trái nhỏ hơn hoặc bằng và số bên phải lớn hơn hoặc bằng (không nên khó khăn với một số phiên bản sửa đổi của tìm kiếm nhị phân)
  4. Chèn, trong khi các khoảng trống rất lớn, nếu không: chỉ reindex (không bao giờ sắp xếp lại) :-)

0

Tôi vừa mới xây dựng một số cấu trúc trừu tượng gọi là hàng đợi lớn và mảng lớn để đơn giản hóa công việc tìm kiếm và sắp xếp dữ liệu lớn trên một máy có bộ nhớ hạn chế. Về cơ bản, thuật toán được sử dụng tương tự như thuật toán bạn đã đề cập ở trên - sắp xếp hợp nhất bên ngoài.

Tôi có thể sắp xếp dữ liệu 128GB (mỗi mục 100 byte) trong 9 giờ trên một máy và sau đó tìm kiếm nhị phân dữ liệu được sắp xếp mà hầu như không có thời gian.

Đây là một bài viết về cách tìm kiếm dữ liệu lớn bằng cách sử dụng hàng đợi lớn nguồn mở và các cấu trúc mảng lớn của tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.