This post originated from an RSS feed registered with .NET Buzz
by Adrian Florea.
Original Post: Quando lo stack overflow diventa sport e C# e J# concorrenti
Feed Title: Web Log di Adrian Florea
Feed URL: /error.aspx?aspxerrorpath=/adrian/Rss.aspx
Feed Description: "You know you've achieved perfection in design, not when you have nothing more to add, but when you have nothing more to take away." Antoine de Saint-Exupery
Eseguendo il foo.exe, arriva la sorpresa: il numero di cicli che la variante J# riesce a fare (159830), supera il numero di cicli della variante C# (159781), fino al messaggio:
Process is terminated due to StackOverflowException.
Incuriosito da questa strana vittoria del J# :-) ho guardato il codice IL generato. Quando compiliamo con C#, il codice IL per i corpi dei metodi main e Main è identico. Quando compiliamo con J# invece, il corpo dell'entry point, main, è inquadrato da:
ldtoken [vjslib]com.ms.vjsharp.lang.ObjectImpl call void [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor(valuetype [mscorlib]System.RuntimeTypeHandle) // qui il corpo del main...
all'inizio e:
// qui il corpo del main... call void [vjslib]com.ms.vjsharp.util.Utilities::cleanupAfterMainReturns()
alla fine.
Cos'ho provato allora? Ho aggiunto nel metodo Main, cioè nell'entry point in C#, l'equivalente (C# e J#) di questi due pezzi in IL. Lo snippet è risultato così:
Ricompilando adesso in C# e in J#, otteniamo lo stesso numero di cicli: 159830!
Si vede però come, RunClassConstructor mangia un po' di stack. Se lo togliamo via lasciando solo cleanupAfterMainReturns, otteniamo addiritura un incremento del numero di cicli nella variante C#: 159914! Dal suo nome sembra che veramente faccia qualche clean up after main returns... :-) Eppure si trova dopo la chiamata di main...