Có một mô hình nào cho việc soạn thảo các hàm cập nhật gia tăng của Google theo kiểu dataflow thuần túy không?


10

Tôi không biết thuật ngữ chính xác khi đặt câu hỏi này, vì vậy tôi sẽ mô tả nó với rất nhiều từ thay vào đó, chịu đựng tôi.

Bối cảnh , chỉ để chúng ta ở cùng một trang: Các chương trình thường chứa bộ nhớ cache - sự đánh đổi thời gian / bộ nhớ. Một lỗi lập trình phổ biến là quên cập nhật giá trị được lưu trong bộ nhớ cache sau khi thay đổi một trong các nguồn / tiền lệ ngược dòng của nó. Nhưng mô hình lập trình dataflow hoặc FRP miễn nhiễm với những sai lầm như vậy. Nếu chúng ta có một số hàm thuần túy và kết nối chúng với nhau trong biểu đồ phụ thuộc có hướng, thì các nút có thể được lưu trữ và sử dụng lại giá trị đầu ra cho đến khi bất kỳ đầu vào nào của hàm thay đổi. Kiến trúc hệ thống này được mô tả trong bài viết Bộ nhớ đệm trong môi trường dựa trên dữ liệu và trong một ngôn ngữ bắt buộc, nó ít nhiều tương tự như ghi nhớ.

Vấn đề : Khi một trong các đầu vào của hàm thay đổi, chúng ta vẫn phải thực thi toàn bộ hàm, loại bỏ đầu ra được lưu trong bộ nhớ cache của nó và tính lại từ đầu. Trong nhiều trường hợp, điều này có vẻ lãng phí đối với tôi. Hãy xem xét một ví dụ đơn giản tạo ra danh sách "top 5 bất cứ thứ gì". Các dữ liệu đầu vào là một danh sách chưa sắp xếp của bất cứ điều gì. Nó được chuyển làm đầu vào cho một hàm tạo ra một danh sách được sắp xếp. Lần lượt là đầu vào cho một chức năng chỉ có 5 mục đầu tiên. Trong mã giả:

input = [5, 20, 7, 2, 4, 9, 6, 13, 1, 45]
intermediate = sort(input)
final_output = substring(intermediate, 0, 5)

Độ phức tạp của hàm sắp xếp là O (N log N). Nhưng hãy xem xét rằng luồng này được sử dụng trong một ứng dụng mà đầu vào chỉ thay đổi một chút tại một thời điểm, bằng cách thêm 1 phần tử. Thay vì sắp xếp lại từ đầu mỗi lần, trên thực tế, O (N) sẽ nhanh hơn để sử dụng chức năng cập nhật danh sách được sắp xếp trong bộ nhớ cache cũ bằng cách chèn phần tử mới vào đúng vị trí. Đây chỉ là một ví dụ - nhiều chức năng "từ đầu" có các bản sao "cập nhật gia tăng" như vậy. Ngoài ra, có thể phần tử mới được thêm thậm chí sẽ không xuất hiện trong phần cuối cùng vì nó nằm sau vị trí thứ 5.

Trực giác của tôi cho thấy có thể bằng cách nào đó có thể thêm các chức năng "cập nhật gia tăng" như vậy vào hệ thống dataflow, bên cạnh các chức năng "từ đầu" hiện có. Tất nhiên, tính toán lại mọi thứ từ đầu phải luôn cho kết quả giống như một loạt các cập nhật gia tăng. Hệ thống phải có thuộc tính rằng nếu mỗi cặp FromScratch-Incremental riêng lẻ luôn cho cùng một kết quả, thì các hàm tổng hợp lớn hơn được xây dựng từ chúng cũng sẽ tự động cho kết quả tương tự.

Câu hỏi : Có thể có một thuật toán hệ thống / kiến ​​trúc / mô hình / meta có thể hỗ trợ cả các hàm FromScratch và các đối tác Tăng dần của chúng, hợp tác cho hiệu quả và được tạo thành các luồng lớn không? Nếu không, tại sao? Nếu ai đó đã nghiên cứu mô hình này và xuất bản nó, nó được gọi là gì và tôi có thể có được một bản tóm tắt ngắn về cách thức hoạt động của nó không?


BTW, trong trường hợp cụ thể của ví dụ của bạn, một giải pháp thậm chí hiệu quả hơn sẽ là sử dụng một đống . Chèn một mục bây giờ chỉ là và tạo danh sách được sắp xếp cập nhật của các giá trị hàng đầu bây giờ chỉ là . k O ( k log n )O(logn)kO(klogn)
j_random_hacker

Câu trả lời:


7

Trường này đã được phát minh nhiều lần và có nhiều tên, chẳng hạn như:

(Và có thể hơn thế nữa.) Những cái đó không giống nhau, nhưng có liên quan.

Paraphrasing Cai et al (1): Có hai cách cốt lõi để thực hiện các thuật toán trực tuyến một cách tổng quát (nghĩa là không tham khảo bất kỳ vấn đề thuật toán cụ thể nào):

  • Gia tăng tĩnh. Phương pháp tiếp cận tĩnh phân tích một chương trình tại thời gian biên dịch và tạo ra một phiên bản gia tăng cập nhật hiệu quả đầu ra của chương trình gốc theo sự thay đổi đầu vào. Phương pháp tiếp cận tĩnh có tiềm năng hiệu quả hơn phương pháp động, bởi vì không yêu cầu ghi sổ khi chạy. Ngoài ra, các phiên bản gia tăng được tính toán thường có thể được tối ưu hóa bằng cách sử dụng các kỹ thuật biên dịch tiêu chuẩn như gập liên tục hoặc nội tuyến. Đây là cách tiếp cận được điều tra trong (1).

  • Tăng động. Phương pháp tiếp cận động tạo ra các biểu đồ phụ thuộc động trong khi chương trình chạy và truyền các thay đổi dọc theo các biểu đồ này. Cách tiếp cận được biết đến nhiều nhất là tính toán tự điều chỉnh của Acar. Ý tưởng chính rất đơn giản: các chương trình thực thi trên đầu vào ban đầu trong môi trường thời gian chạy nâng cao theo dõi các phụ thuộc giữa các giá trị trong biểu đồ phụ thuộc động; kết quả trung gian được lưu trữ. (Như bạn có thể tưởng tượng, điều này có xu hướng sử dụng nhiều bộ nhớ và nhiều nghiên cứu trong lĩnh vực này là về cách hạn chế sử dụng bộ nhớ.) Sau đó, thay đổi lan truyền đầu vào thông qua biểu đồ phụ thuộc từ đầu vào thay đổi thành kết quả, cập nhật cả trung gian và kết quả cuối cùng; quá trình xử lý này thường hiệu quả hơn so với tính toán lại. Tuy nhiên, việc tạo các biểu đồ phụ thuộc động áp đặt một chi phí lớn cho hệ số không đổi trong thời gian chạy, dao động từ 2 đến 30 trong các thử nghiệm được báo cáo.

Ngoài ra, người ta luôn có thể thử và đưa ra 'bằng tay' với phiên bản trực tuyến của một thuật toán nhất định. Điều này có thể khó khăn.


(1) Y. Cai, PG Giarrusso, T. Rendel, K. Ostermann, Lý thuyết về sự thay đổi của các ngôn ngữ bậc cao: Tăng dần Calcul-Tính toán bằng cách phân biệt tĩnh .


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.