23
août
2007
Optimisation de l’IL généré par le compilateur
août
2007
Dans le cas d’une méthode (non statique) qui renvoit this, l’IL fait un pop même s’il a besoin de l’instance juste derrière :
private static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("azerty");
Console.WriteLine(sb);
}
{
StringBuilder sb = new StringBuilder();
sb.Append("azerty");
Console.WriteLine(sb);
}
donne l’IL suivant :
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] class [mscorlib]System.Text.StringBuilder sb)
L_0000: nop
L_0001: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: ldstr "azerty"
L_000d: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0012: pop
L_0013: ldloc.0
L_0014: call void [mscorlib]System.Console::WriteLine(object)
L_0019: nop
L_001a: ret
}
{
.entrypoint
.maxstack 2
.locals init (
[0] class [mscorlib]System.Text.StringBuilder sb)
L_0000: nop
L_0001: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_0006: stloc.0
L_0007: ldloc.0
L_0008: ldstr "azerty"
L_000d: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0012: pop
L_0013: ldloc.0
L_0014: call void [mscorlib]System.Console::WriteLine(object)
L_0019: nop
L_001a: ret
}
alors qu’il pourrait être optimisé comme suit :
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
L_0001: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_0008: ldstr "azerty"
L_000d: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0014: call void [mscorlib]System.Console::WriteLine(object)
L_001a: ret
}
{
.entrypoint
.maxstack 2
L_0001: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
L_0008: ldstr "azerty"
L_000d: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
L_0014: call void [mscorlib]System.Console::WriteLine(object)
L_001a: ret
}
Dans l’exemple, il est dommage de décharger la pile de l’instance de StringBuilder pour remettre la même.
Petite précision tout de même, contrairement à mon post précédent sur les optimisations du compilateur, dans ce cas, le compilateur est obligé de faire cela. En effet, il faudrait sinon qu’il teste toutes les méthodes qui retourne un objet du même type que l’instance sur laquelle elles s’appliquent pour s’assurer que c’est bien this qui est retourné.