Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
Mostrando entradas con la etiqueta optimización. Mostrar todas las entradas
Mostrando entradas con la etiqueta optimización. Mostrar todas las entradas
martes, 31 de enero de 2023
.NET

Seguimos hablando de problemas que es habitual solucionarlos de una determinada manera, quizás por costumbre, quizás por pereza, o tal vez por desconocimiento de que haya otras formas de hacerlo. En este caso, hablaremos de una necesidad que probablemente habréis tenido alguna vez: transformar un GUID a una cadena de caracteres eliminando los habituales guiones.

Es decir, dado un GUID con el valor 1f5772a6-91ca-4035-8b6d-9676ec6d0eaa, queremos obtener su representación como cadena de caracteres, pero eliminando los guiones, resultando "1f5772a691ca40358b6d9676ec6d0eaa".

martes, 8 de noviembre de 2022
C#

En código que veo, incluso escrito por mí un tiempo atrás, es muy habitual encontrar comparaciones de cadenas de caracteres en las que, para asegurar que el casing no sea tenido en cuenta, se fuerza una conversión de alguno de los operandos, o incluso ambos, a mayúsculas o minúsculas.

En escenarios muy simples esto funcionará bien y no tendrá contraindicaciones especialmente graves para nuestro sistema. Veamos unos ejemplos:

// Ejemplo 1: conversión de un único operando
int Calculate(string op, int a, int b)
{
    // Pasamos a minúsculas el operador para
    // asegurar que encaja con la constante
    if(op.ToLower()=="add")
    {
        return a+b;
    } 
    else if(op.ToLower()=="sub")
    {
        return a-b;
    }
    ...
}

// Ejemplo  2: conversión de ambos operandos
bool AreBrothers(User user1, User user2)
{
    // Pasamos a mayúsculas ambos apellidos por
    // si alguno se ha escrito usando otro casing
    var areBrothers = user1.Surname.ToUpper() == user2.Surname.ToUpper();
    return areBrothers;
}

Sin embargo, aunque pueda parecer despreciable, estas operaciones de transformación a mayúsculas o minúsculas tienen un coste importante, que se pone especialmente de manifiesto cuando estamos hablando de aplicaciones con mucha carga de usuarios, alojada en infraestructura muy ajustada o cuando se requiere un rendimiento extremo.

miércoles, 3 de abril de 2013
ASP.NETLa nueva versión de System.Web.Optimization traerá (aún está en beta) algunas novedades interesantes al sistema de bundling que se incluye de serie en los proyectos ASP.NET MVC y se distribuye a través de Nuget en el paquete Microsoft.AspNet.Web.Optimization.

En particular, vamos a centrarnos en una característica muy práctica si queremos utilizar una Content Delivery Network (CDN) externa (como la de Microsoft, Google o incluso una propia) para delegar a ella la carga de bibliotecas de script comunes, pero queremos a la vez proporcionar una alternativa local por si acaso ésta fallase debido a cualquier motivo.
martes, 18 de octubre de 2011
ASP.NET MVCHabía comentado que una de las novedades que ya podíamos disfrutar en la developer preview de MVC 4 era el sistema de compactación y minimización de scripts y CSS, y que, además de ser bastante útil y sencillo, podíamos utilizarlo a día de hoy en nuestras aplicaciones MVC 3 e incluso en ASP.NET Webforms.

Este mecanismo hace posible la creación de bundles, o paquetes de uno o varios archivos de scripts o estilos, que son optimizados en tamaño por el servidor y cargados desde las páginas en una única petición. El proceso de compactación se realizaría en servidor, pero sólo la primera vez, quedando almacenado en caché para las peticiones posteriores.

martes, 3 de julio de 2007

Sí, he de admitir que es una pregunta rara, pero me la hago desde que conocí hace ya muchos años que en lenguaje C podía incrementar una variable de tres formas, autoincrementando (var++), incrementando en uno (var+=1) o sumando la unidad (var=var+1)... ¿hay alguna diferencia entre ellas? Esta absurda inquietud la he mantenido durante lustros, viendo cómo estas construcciones se propagaban hacia lenguajes más actuales con sintaxis basada en C, como C++, C# o Java.

Claro está que desde el punto de vista semántico no existe diferencia alguna, pues todas comparten el mismo objetivo: incrementar en una unidad la variable indicada. Sin embargo, ¿existe diferencia en la forma en que el compilador las trata? ¿se genera código más eficiente utilizando una de ellas, o son absolutamente iguales?

Para responder a esta cuestión, he realizado una pequeña aplicación en varios lenguajes y plataformas, generado posteriormente un ejecutable y desensamblado el binario de salida con la herramienta correspondiente en cada caso. A continuación describo los resultados obtenidos.

En primer lugar, he atacado al lenguaje C, compilado bajo Linux con gcc y desensamblando con ndisasm.

La aplicación con la que he realizado las comprobaciones era la siguiente:

#include "stdio.h"
main()
{
int i;
i = 0x99f;
i++;
i += 1;
i = i + 1;
printf("Vale: %d", i);
}

Nota: el 0x99f con el que inicializo la variable "i" me sirve para buscar rápidamente en el código ensamblador dónde se encuentran las instrucciones a estudiar.

Bueno, a lo que vamos. Una vez compilado y desensamblado, el código que encuentro es:

...
mov word [di-0x8], 0x99f
add [bx+si], al
add word [di-0x8], byte +0x1
add word [di-0x8], byte +0x1
add word [di-0x8], byte +0x1
...

Según parece, el compilador gcc ha generado exactamente el mismo código en todos los casos. La verdad es que este resultado me ha sorprendido un poco, esperaba que se utilizaran en los primeros casos las instrucciones de incremento directo del procesador, optimizando el binario generado, pero no ha sido así. A la vista de esto, he preguntado a Google y parece ser que es un comportamiento recomendado para los compiladores de C, por lo que podemos dar por concluida esta línea de la investigación.

A continuación he pasado a C#, compilando tanto con .NET Framework de Microsoft como con Mono. La aplicación era similar a la anterior (traducida, obviamente), y el resultado en lenguaje intermedio (MSIL), obtenido tanto con ildasm como con su equivalente monodis es el mismo:

[...]
//000011: int i = 0x99f;
IL_0001: ldc.i4 0x99f
IL_0006: stloc.0
//000012: i++;
IL_0007: ldloc.0
IL_0008: ldc.i4.1
IL_0009: add
IL_000a: stloc.0
//000013: i += 1;
IL_000b: ldloc.0
IL_000c: ldc.i4.1
IL_000d: add
IL_000e: stloc.0
//000014: i = i + 1;
IL_000f: ldloc.0
IL_0010: ldc.i4.1
IL_0011: add
IL_0012: stloc.0
[...]

Podemos observar que, como en el caso anterior, el compilador no diferencia entre el tipo de incremento que utilicemos, da exactamente igual.

Por último, probamos con Java 5, utilizando el JDK de Sun. La aplicación es exactamente igual a las anteriores, con la correspondiente adaptación a este lenguaje, algo así como:

class Prueba
{
public static void main(String[] args)
{
int i = 0x99f;
i++;
i+=1;
i=i+1;
System.out.println("Vale: " + i);
}
}

El compilador de Java, en este caso, sí hace distinciones entre los dos primeros modelos de incremento y el tercero. El autoincremento e incremento los genera exactamente iguales, creando una instrucción bytecode de incremento en una unidad, mientras que el último lo crea como una suma; supongo que la primera será posible optimizarla y su ejecución será más rápida:

 0: sipush 2463
3: istore_1
// i++:
4: iinc 1, 1
// i+=1:
7: iinc 1, 1
// i=i+1:
10: iload_1
11: iconst_1
12: iadd
13: istore_1
// Resto...
[...]

En resumidas cuentas, podemos usar con toda tranquilidad cualquiera de los operadores de suma para incrementar una variable, puesto que el código será igual de eficiente (o poco eficiente, según se mire) y prácticamente no tendrá incidencia en la velocidad de ejecución, al menos con las opciones de compilación por defecto. Sólo Java parece estar adelantado en este sentido, pues es capaz de distinguir estos casos.

Y sí, era una inquietud de lo más absurda, lo dije desde el principio, pero me he quedado muy tranquilo, y con una duda menos en mi saco de ignorancia.