là các trình biên dịch như Javac đủ thông minh để phát hiện khi một phương thức là một hàm thuần túy.
Đó không phải là một câu hỏi "đủ thông minh". Cái này được gọi là Phân tích độ tinh khiết và có thể chứng minh là không thể trong trường hợp chung: nó tương đương với việc giải quyết vấn đề dừng.
Bây giờ, tất nhiên, tối ưu hóa làm những điều không thể chứng minh mọi lúc, "có thể chứng minh là không thể trong trường hợp chung" không có nghĩa là nó không bao giờ hoạt động, nó chỉ có nghĩa là nó không thể hoạt động trong mọi trường hợp. Vì vậy, trên thực tế, có các thuật toán để kiểm tra xem một hàm có thuần hay không, chỉ là kết quả sẽ không thường xuyên hơn là "Tôi không biết", điều đó có nghĩa là vì lý do an toàn và chính xác, bạn cần phải giả sử rằng chức năng đặc biệt này có thể không tinh khiết.
Và ngay cả trong trường hợp nó làm làm việc, các thuật toán rất phức tạp và tốn kém.
Vì vậy, đó là vấn đề # 1: nó chỉ hoạt động cho các trường hợp đặc biệt .
Vấn đề # 2: Thư viện . Để một hàm được thuần túy, nó chỉ có thể gọi các hàm thuần túy (và các hàm đó chỉ có thể gọi các hàm thuần túy, v.v.). Javac rõ ràng chỉ biết về Java và nó chỉ biết về mã mà nó có thể nhìn thấy. Vì vậy, nếu hàm của bạn gọi một hàm trong một đơn vị biên dịch khác, bạn không thể biết liệu nó có thuần túy hay không. Nếu nó gọi một chức năng được viết bằng ngôn ngữ khác, bạn không thể biết. Nếu nó gọi một chức năng trong thư viện thậm chí chưa được cài đặt, bạn không thể biết. Và như thế.
Điều này chỉ hoạt động, khi bạn có phân tích toàn bộ chương trình, khi toàn bộ chương trình được viết bằng cùng một ngôn ngữ và tất cả được biên dịch cùng một lúc. Bạn không thể sử dụng bất kỳ thư viện.
Vấn đề # 3: Lập kế hoạch . Một khi bạn đã tìm ra phần nào là thuần túy, bạn vẫn phải sắp xếp chúng để tách các chủ đề. Hay không. Bắt đầu và dừng các chủ đề rất tốn kém (đặc biệt là trong Java). Ngay cả khi bạn giữ một nhóm luồng và không bắt đầu hoặc dừng chúng, chuyển đổi ngữ cảnh luồng cũng tốn kém. Bạn cần chắc chắn rằng tính toán sẽ chạy lâu hơn đáng kể so với thời gian cần thiết để lên lịch và chuyển đổi ngữ cảnh, nếu không bạn sẽ mất hiệu suất, không đạt được nó.
Như bạn có thể đoán được bây giờ, việc tính toán sẽ mất bao lâu để tính toán trong trường hợp chung (chúng ta thậm chí không thể biết liệu nó có mất một khoảng thời gian hữu hạn hay không, kể cả bao nhiêu thời gian) và khó khăn và tốn kém ngay cả trong trường hợp đặc biệt
Ngoài ra: Javac và tối ưu hóa . Lưu ý rằng hầu hết các triển khai javac không thực sự thực hiện nhiều tối ưu hóa. Ví dụ, việc triển khai javac của Oracle dựa vào công cụ thực thi cơ bản để thực hiện tối ưu hóa . Điều này dẫn đến một loạt vấn đề khác: giả sử, javac đã quyết định rằng một hàm cụ thể là thuần túy và nó đủ đắt, và do đó, nó biên dịch nó để được thực thi trên một luồng khác. Sau đó, trình tối ưu hóa của nền tảng (ví dụ: trình biên dịch JIT HotSpot C2) xuất hiện và tối ưu hóa toàn bộ chức năng. Bây giờ, bạn có một chủ đề trống không làm gì. Hoặc, hãy tưởng tượng, một lần nữa, javac quyết định lên lịch một chức năng trên một luồng khác và trình tối ưu hóa nền tảng có thể tối ưu hóa nó hoàn toàn, ngoại trừ nó không thể thực hiện nội tuyến trên các ranh giới luồng, và do đó, một chức năng có thể được tối ưu hóa hoàn toàn hiện đang được thực hiện một cách không cần thiết.
Vì vậy, làm một cái gì đó như thế này chỉ thực sự có ý nghĩa nếu bạn có một trình biên dịch duy nhất thực hiện hầu hết các tối ưu hóa trong một lần, để trình biên dịch biết và có thể khai thác tất cả các tối ưu hóa khác nhau ở các cấp độ khác nhau và tương tác của chúng với nhau.
Lưu ý rằng, ví dụ, trình biên dịch JIT HotSpot C2 thực sự không thực hiện một số tính năng tự động vector hóa, mà còn là một hình thức tự động song song.