Java'da yöntem parametrelerini nihai olarak bildirmek için herhangi bir performans nedeni var mı?


117

Java'da yöntem parametrelerini nihai olarak bildirmek için herhangi bir performans nedeni var mı?

De olduğu gibi:

public void foo(int bar) { ... }

Karşı:

public void foo(final int bar) { ... }

Bunun barsadece okunduğunu ve içinde asla değiştirilmediğini varsayarsak foo().


Bir yöntem parametresini final olarak ilan edip etmediğinizi derleyicinin neden umursayacağına dair bir neden düşünemiyorum. Ancak bu sorunun gerçek cevabı - biri son parametrelerle diğeri normal parametrelerle olmak üzere iki işlev yazın. Her birini milyon kez çalıştırın ve gözle görülür bir çalışma süresi farkı olup olmadığına bakın. Performans konusunda endişeleniyorsanız, kodunuz üzerinde bazı profilleme çalışmaları yapmak ve sizi tam olarak neyin yavaşlattığını bulmak çok önemlidir. Neredeyse kesinlikle beklediğiniz gibi değil :)
Mike Blandford

1
Asla mikro ölçütler yazmamanızı öneririm. JIT'in hangi optimizasyonu ne zaman yapabileceğini bilmiyorsunuz ve sadece "basit bir test vakası" yaparak nasıl davrandığına dair muhtemelen yanlış bir fikir
edinirsiniz

iyi olabilir, ancak burada kimse bir mikro ölçüt yazmadı veya önermedi ...
Kip

1
@Mike Blandford'un cevabı bir mikro kıyaslama kullanmayı öneriyor, değil mi?
Ben Page

Java'da mikro ölçütler yazmak çok zor bir şey
Edmondo1984

Yanıtlar:


97

Son anahtar sözcük, yerel değişkenler ve parametreler için sınıf dosyasında görünmez, bu nedenle çalışma zamanı performansını etkileyemez. Tek kullanım alanı, değişkenin değiştirilmemesi (çoğu kişinin kullanımı için şüpheli bir neden olarak gördüğü) niyetini kodlayıcılara açıklığa kavuşturmak ve anonim iç sınıflarla uğraşmaktır.

Yöntemler, değiştiriciden bağımsız olarak, çalışma zamanında en iyi duruma getirici derleyici tarafından her halükarda satır içine alınacağından, yöntemin kendisindeki son değiştiricinin herhangi bir performans kazancına sahip olup olmadığı konusunda birçok argüman vardır. Bu durumda, sadece yöntemin geçersiz kılınmasını kısıtlamak için de kullanılmalıdır.


5
Yine de son değişkenlerin / parametrelerin döngü değişkenleri olarak optimize edilebileceğini düşünürdünüz ... ama iyi bir derleyici / çalışma zamanı yine de final olmadan bunu çözebilmelidir ...
John Gardner

9
İki yöntem arasındaki tek fark yerel değişkenlerin "kesinliği" olduğunda, Sun'ın derleyicisinin marjinal olarak daha kısa bayt kodu yaydığını gördüm. Mikro optimizasyonlar gerçektir ve derleyiciler aslında onları yapar. Tabii ki asıl önemli olan, JIT'in bayt kodu ile ne yaptığıdır ve yerel referanslar, bayt koduna göre derlendiğinde "kesinliklerini" kaybeder. Nihai yerel değişkenler hakkında bu kadar çok spekülasyonun olmasının nedeni budur: Sonuçların ne olduğu oldukça belirleyici değildir. Ancak, nihai yerelleri kullanmak bayt kodunu etkileyebilir - değeri ne olursa olsun.
Christopher Schultz

Belirleyici olmadığı için, optimizasyona bağlı olmanın da bir yolu yoktur. Tabii ki, 2008'deki orijinal cevaptan bu yana
Robin

15

Son parametrenin tek yararı, anonim iç içe geçmiş sınıflarda kullanılabilmesidir. Bir parametre asla değiştirilmezse, derleyici bunu, son değiştirici olmadan bile normal çalışmasının bir parçası olarak zaten algılayacaktır. Hataların beklenmedik bir şekilde atanan bir parametreden kaynaklanması oldukça nadirdir - yöntemleriniz bu düzeyde mühendislik gerektirecek kadar büyükse, onları küçültün - çağırdığınız yöntemler parametrelerinizi değiştiremez.


8
"Hataların beklenmedik bir şekilde atanan bir parametreden kaynaklanması oldukça nadirdir". Düşündüğünüzden daha yaygın ...
RAY

2
@RAY haklı olabilirsin, aslında bu iddiayı destekleyecek hiçbir veriye (kendi deneyimlerimin ötesinde) sahip değilim.
Dobes Vandermeer

@DobesVandermeer daha doğrusu, bu gerçekten bir "son parametreye fayda " değil. Açıkladığınız şey, anonim iç içe sınıfın yerel kapsamı tarafından görünür kılınacak herhangi bir yerel değişken için (parametreleri de dahil ediyorum) gerekli sözdizimidir.
swooby

0

JIT derleyicileri gibi sınıf yüklemesinden sonra çalışan derleyiciler, son yöntemlerden yararlanabilir. Sonuç olarak, nihai olarak beyan edilen yöntemlerin bazı performans faydaları olabilir.

http://www.javaperformancetuning.com/tips/final.shtml

Oh ve başka bir iyi kaynak

http://mindprod.com/jgloss/final.html


10
Soru, nihai olarak beyan edilen ve performansa etkisi olmayan parametrelerle ilgiliydi.
Robin

Modern JIT'in (Hotspot) finalinde, parametrelere veya sınıfa uygulanmış olsun, hiçbir (ölçülebilir) performans etkisi yoktur
kohlerm

2
Bağlantı kurduğunuz iki makale, finalin geliştiriciler için daha çok anlamsal bir işaret olduğunu ve JIT derleyicilerinin final kullanabileceğini (ancak diğerlerinin de belirttiği gibi, bu bilgiye gerçekten ihtiyaç duymadıklarını) öne sürüyor. Dolayısıyla son, oldukça anlamsaldır; bu, modern C / ++ derleyicilerinin değişkenlerin ve yöntemlerin sabitliğini açıkça const olarak işaretlenmemiş olsalar bile çıkarabilme yeteneğiyle paraleldir.
ron

0

Yöntem içinde bildirilmiş son olmayan yerel değişkenlerin kullanılmasının yukarıda bir noktaya daha dikkat edin - iç sınıf örneği yığın çerçevesini aşabilir, bu nedenle iç nesne hala canlıyken yerel değişken yok olabilir.


-2

Derleyicinin int gibi ilkel bir türe sahip tüm özel statik son değişkenleri kaldırabileceğini ve bunları bir C ++ makrosunda olduğu gibi doğrudan kodda satır içi yapabileceğini varsayıyorum.

Bununla birlikte, bunun pratikte yapılıp yapılmadığı konusunda hiçbir fikrim yok, ancak biraz hafıza tasarrufu sağlamak için yapılabilir.


Soru özel statc final değişkenleri hakkında değil.
Lorne Markisi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.