¿Cuántas veces nos hemos preguntado entre dos opciones cuál es más óptima? Hoy os muestro una utilidad que os puede ayudar.
Tabla de contenidos
Lo primero que hay que saber para ver cómo se optimiza en el lenguaje que trabajamos es ver cómo funciona el mismo. En el caso de C# (java es similar), hay 2 fases principales:
Viendo el gráfico anterior, podemos apreciar como el compilar puede realizar optimizaciones tanto en la generación del código C#, como en la generación del IL(Intermediate Language) y en tiempo de ejecución, en la generación de las instrucciones que ejecutará nuestra CPU.
Sabiendo esto, estaría bien poder usar una herramienta que nos muestre tanto el código IL, como el ASM, resultado de la compilación de nuestro código fuente C#. Esta tarea la podemos hacer online con SharpLab.io
Una de las características de C# 6, son los expression-bodied members, lo que nos permite utilizar esta sintaxis:
public string GetName() => "Juan";
En lugar de:
public string GetName(){
return "Juan";
}
En el siguiente enlace podéis ver cómo se comporta el código anterior respecto a su rendimiento.
En modo debug, el IL resultante del método necesita ejecutar más instrucciones que en el caso del expression-bodied member. Además, a simple vista se puede ver que es más lento.
.method public hidebysig static
string GetName () cil managed
{
// Method begins at RVA 0x2050
// Code size 11 (0xb)
.maxstack 1
.locals init (
[0] string
)
IL_0000: nop
IL_0001: ldstr "Hola Juan"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
} // end of method C::GetName
.method public hidebysig specialname static
string get_GetNameInline () cil managed
{
// Method begins at RVA 0x2067
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "Hola Juan"
IL_0005: ret
} // end of method C::get_GetNameInline
En el caso del ASM, también ocurre lo mismo:
C.GetName()
L0000: push ebp
L0001: mov ebp, esp
L0003: push eax
L0004: cmp dword [0x17db1578], 0x0
L000b: jz L0012
L000d: call 0x73864330
L0012: xor edx, edx
L0014: mov [ebp-0x4], edx
L0017: nop
L0018: mov eax, [0xf1cf73c]
L001e: mov [ebp-0x4], eax
L0021: nop
L0022: jmp L0024
L0024: mov eax, [ebp-0x4]
L0027: mov esp, ebp
L0029: pop ebp
L002a: ret
C.get_GetNameInline()
L0000: push ebp
L0001: mov ebp, esp
L0003: cmp dword [0x17db1578], 0x0
L000a: jz L0011
L000c: call 0x73864330
L0011: mov eax, [0xf1cf73c]
L0017: pop ebp
L0018: ret
Como todos sabréis, el rendimiento siempre se mide en modo release, que es donde el compilador aplica mayor número de optimizaciones. Ahora el IL es exactamente igual:
// Methods
.method public hidebysig static
string GetName () cil managed
{
// Method begins at RVA 0x2050
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "Hola Juan"
IL_0005: ret
} // end of method C::GetName
.method public hidebysig specialname static
string get_GetNameInline () cil managed
{
// Method begins at RVA 0x2057
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "Hola Juan"
IL_0005: ret
} // end of method C::get_GetNameInline
En el caso del ASM, este es muy simple, carga el string ya generado en memoria a un registro y lo devuelve:
C.GetName()
L0000: mov eax, [0xf1cf73c]
L0006: ret
C.get_GetNameInline()
L0000: mov eax, [0xf1cf73c]
L0006: ret
La programación asíncrona en C# permite delegar en el sistema operativo la gestión de las operaciones de entrada/salida bloqueantes (I/O), de manera que se pueden liberar los hilos que realizan estas operaciones, para ser reutilizados por otras partes del código. Esto permite grandes mejoras de rendimiento, como se puede ver en la siguiente infografía:
Como se puede ver en el artículo:
Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.
Donald Knuth
En los últimos tiempos no he podido escribir con toda la frecuencia que me gustaría,…
Uno de los problemas más comunes a los que se enfrentan los usuarios que empiezan…
Cuando empiezas un proyecto hay una serie de aspectos comunes que suelen ser resueltos mediante…
Si alguna vez has tenido que realizar un desarrollo de front-end seguramente te habrás dado…
Una vez que una persona ya ha aprendido lo básico sobre un lenguaje de programación,…
Hoy en día, un gran porcentaje de los proyectos que se desarrollan son páginas webs.…