adalah kompiler seperti Javac cukup pintar untuk mendeteksi kapan suatu metode adalah fungsi murni.
Ini bukan pertanyaan "cukup pintar". Ini disebut Analisis Kemurnian dan terbukti mustahil dalam kasus umum: ini setara dengan menyelesaikan Masalah Pemutusan Hubungan.
Sekarang, tentu saja, pengoptimal melakukan hal-hal yang terbukti mustahil sepanjang waktu, "terbukti tidak mungkin dalam kasus umum" tidak berarti tidak pernah berhasil, itu hanya berarti tidak dapat berfungsi dalam semua kasus. Jadi, sebenarnya ada algoritma untuk memeriksa apakah suatu fungsi murni atau tidak, hanya saja lebih sering hasilnya adalah "Saya tidak tahu", yang berarti bahwa untuk alasan keamanan dan kebenaran, Anda perlu mengasumsikan bahwa fungsi khusus ini mungkin tidak murni.
Dan bahkan dalam kasus di mana tidak bekerja, algoritma yang kompleks dan mahal.
Jadi, itulah Masalah # 1: itu hanya berfungsi untuk kasus khusus .
Masalah # 2: Perpustakaan . Agar suatu fungsi menjadi murni, ia hanya dapat memanggil fungsi murni (dan fungsi tersebut hanya dapat memanggil fungsi murni, dan seterusnya dan seterusnya). Javac jelas hanya tahu tentang Java, dan hanya tahu tentang kode yang dapat dilihatnya. Jadi, jika fungsi Anda memanggil fungsi di unit kompilasi lain, Anda tidak bisa tahu apakah itu murni atau tidak. Jika itu memanggil fungsi yang ditulis dalam bahasa lain, Anda tidak bisa tahu. Jika itu memanggil fungsi di perpustakaan yang bahkan mungkin belum diinstal, Anda tidak bisa tahu. Dan seterusnya.
Ini hanya berfungsi, ketika Anda memiliki analisis seluruh program, ketika seluruh program ditulis dalam bahasa yang sama, dan semua dikompilasi sekaligus dalam satu waktu. Anda tidak dapat menggunakan perpustakaan apa pun.
Masalah # 3: Penjadwalan . Setelah Anda mengetahui bagian mana yang murni, Anda masih harus menjadwalkannya untuk memisahkan utas. Atau tidak. Memulai dan menghentikan utas sangat mahal (terutama di Jawa). Bahkan jika Anda menyimpan kumpulan utas dan tidak memulai atau menghentikannya, pergantian konteks utas juga mahal. Anda harus yakin bahwa perhitungan akan berjalan jauh lebih lama daripada waktu yang diperlukan untuk menjadwalkan dan mengubah konteks, jika tidak, Anda akan kehilangan kinerja, bukan memperolehnya.
Seperti yang mungkin sudah Anda tebak sekarang, mencari tahu berapa lama perhitungan akan terbukti tidak mungkin dalam kasus umum (kami bahkan tidak dapat menentukan apakah akan membutuhkan waktu yang terbatas, apalagi berapa lama) dan sulit dan mahal bahkan di kasus khusus.
Selain: Javac dan optimisasi . Perhatikan bahwa sebagian besar implementasi javac tidak benar-benar melakukan banyak optimasi. Implementasi Oracle dari javac, misalnya, bergantung pada mesin eksekusi yang mendasari untuk melakukan optimasi . Ini mengarah ke serangkaian masalah lain: katakanlah, javac memutuskan bahwa fungsi tertentu murni dan cukup mahal, sehingga mengkompilasinya untuk dieksekusi pada utas yang berbeda. Kemudian, pengoptimal platform (misalnya, kompiler JIT HotSpot C2) datang dan mengoptimalkan seluruh fungsi. Sekarang, Anda memiliki utas kosong yang tidak melakukan apa-apa. Atau, bayangkan, sekali lagi, javac memutuskan untuk menjadwalkan fungsi pada utas yang berbeda, dan pengoptimal platform bisa mengoptimalkannya sepenuhnya, kecuali itu tidak dapat melakukan inlining melintasi batas-batas thread, dan fungsi yang dapat dioptimalkan sepenuhnya sepenuhnya sekarang dieksekusi tanpa perlu.
Jadi, melakukan sesuatu seperti ini hanya benar-benar masuk akal jika Anda memiliki satu kompiler membuat sebagian besar optimasi dalam sekali jalan, sehingga kompiler mengetahui dan dapat mengeksploitasi semua optimasi yang berbeda di tingkat yang berbeda dan interaksinya satu sama lain.
Perhatikan bahwa, misalnya, kompiler HotSpot C2 JIT benar - benar melakukan beberapa auto-vektorisasi, yang juga merupakan bentuk paralelisasi otomatis.