Belirtilen diğer cevaplar gibi, CLR kuyruk arama optimizasyonunu destekliyor ve tarihsel olarak ilerici iyileştirmeler altında görünüyor. Ancak C # ile desteklenmesinin Proposal
git deposunda C # programlama dilinin tasarımı için açık bir sorunu var Destek kuyruk özyinelemesi # 2544 .
Orada bazı yararlı ayrıntılar ve bilgiler bulabilirsiniz. Örneğin @jaykrell bahsedildi
Bildiklerimi vereyim.
Bazen arka arkaya çağrı, performans açısından bir kazan-kazan demektir. CPU'dan tasarruf edebilir. jmp, call / ret'den daha ucuzdur. Yığını kaydedebilir. Daha az yığına dokunmak daha iyi bir konum sağlar.
Ara sıra bazen performans kaybıdır, yığın kazanır. CLR, aranan uca, arayanın aldığından daha fazla parametreyi iletmek için karmaşık bir mekanizmaya sahiptir. Parametreler için özellikle daha fazla yığın alanı demek istiyorum. Bu yavaş. Ancak yığını korur. Bunu sadece kuyrukla yapacak. önek.
Arayan parametreleri, aranan parametrelerden yığın büyüklüğünde ise, genellikle oldukça kolay bir kazan-kazan dönüşümüdür. Parametre konumunun yönetilen konumdan tamsayı / kayan sayıya değişmesi ve hassas StackMap'ler ve benzerlerinin oluşturulması gibi faktörler olabilir.
Şimdi, sabit / küçük yığınla keyfi olarak büyük verileri işleyebilmek amacıyla kuyruk çağrısının ortadan kaldırılmasını gerektiren algoritmaların başka bir açısı var. Bu performansla ilgili değil, koşma yeteneği ile ilgili.
Ayrıca şunu da belirteyim (ekstra bilgi olarak), İsim System.Linq.Expressions
alanındaki ifade sınıflarını kullanarak derlenmiş bir lambda oluşturduğumuzda, açıklamasında açıklandığı gibi 'tailCall' adında bir argüman vardır.
Oluşturulan ifadeyi derlerken kuyruk çağrısı optimizasyonunun uygulanıp uygulanmayacağını gösteren bir bool.
Henüz denemedim ve sorunuzla ilgili olarak nasıl yardımcı olacağından emin değilim, ancak Muhtemelen birisi deneyebilir ve bazı senaryolarda faydalı olabilir:
var myFuncExpression = System.Linq.Expressions.Expression.Lambda<Func< … >>(body: … , tailCall: true, parameters: … );
var myFunc = myFuncExpression.Compile();
preemptive
(örneğin faktöryel algoritma) veNon-preemptive
(örneğin, ackermann'ın işlevi) bir kitap okuyordum . Yazar, bu çatallanmanın ardında uygun bir gerekçe göstermeden bahsettiğim sadece iki örnek verdi. Bu çatallanma, kuyruk ve kuyruk olmayan özyinelemeli işlevlerle aynı mı?