Calidad y seguridad
El software ha ido creciendo durante años y cada versión ha traído nuevas funciones. En algún momento, con archivos grandes, los usuarios esperan minutos a que haya una respuesta y la ventana muestra «No responde». Las optimizaciones sueltas hechas a ojo rara vez ayudan en ese caso. Hace falta un procedimiento sistemático.
Primero medir, después cambiar
La causa más frecuente de una optimización inútil es adivinar. Mida primero, y hágalo con datos realistas: con los grandes diseños, series de mediciones o proyectos con los que sus usuarios realmente esperan. Un perfilador, por ejemplo el generador de perfiles de rendimiento de Visual Studio, muestra dónde se va realmente el tiempo. Registre una medición de partida para tres a cinco procesos típicos. Solo así podrá demostrar después lo que ha aportado una medida.
Recopilar y ordenar los puntos de mejora
En un software que ha ido creciendo rara vez hay un único freno. Casi siempre son muchos puntos que se suman. Recójalos en un documento conceptual y evalúe cada uno según su efecto y su esfuerzo. Candidatos típicos son:
| Punto de mejora | Síntoma típico | Posible medida |
|---|---|---|
| Cálculo largo en el hilo de la interfaz | La ventana se congela | Trasladar el cálculo a segundo plano |
| Cálculo repetido | El mismo resultado se vuelve a calcular con cada redibujado | Almacenar los resultados en caché y volver a calcular solo si hay cambios |
| Estructura de datos inadecuada | El tiempo de ejecución crece de forma desproporcionada con la cantidad de datos | Buscar mediante Dictionary o un índice espacial en lugar de en listas largas |
| Muchos accesos pequeños | Accesos individuales a la base de datos o a archivos dentro de bucles | Agrupar los accesos |
| Redibujado constante | La interfaz se actualiza con cada cambio individual | Acumular los cambios y actualizar una sola vez |
| Presión sobre la memoria | Muchos objetos de vida corta, recolección de elementos no utilizados frecuente | Reutilizar objetos, evitar copias innecesarias |
Aplique primero los puntos más eficaces y vuelva a medir tras cada paso.
Calcular en segundo plano
No todos los cálculos se pueden acelerar. Pero casi todos se pueden organizar de modo que el usuario pueda seguir trabajando. En .NET esto se consigue con async y await: el cálculo se ejecuta en un hilo en segundo plano, la interfaz sigue siendo utilizable y después el resultado vuelve a llegar al hilo de la interfaz. Un ejemplo para WPF:
private CancellationTokenSource abbruch;
private async void BerechnenButton_Click(object sender, RoutedEventArgs e)
{
berechnenButton.IsEnabled = false;
abbruch = new CancellationTokenSource();
var fortschritt = new Progress<int>(prozent => fortschrittsBalken.Value = prozent);
try
{
// Copiar los datos en el hilo de la interfaz y calcular en segundo plano solo con la copia
ModellDaten daten = modell.ErstelleKopie();
Ergebnis ergebnis = await Task.Run(
() => Berechnung.Starte(daten, fortschritt, abbruch.Token));
ZeigeErgebnis(ergebnis);
}
catch (OperationCanceledException)
{
statusText.Text = "Berechnung abgebrochen.";
}
finally
{
berechnenButton.IsEnabled = true;
}
}
private void AbbrechenButton_Click(object sender, RoutedEventArgs e)
{
abbruch?.Cancel();
}
Importante: en segundo plano, el cálculo no debe tocar ni los controles ni la base de datos de dibujo de un sistema CAD. Trabaja con una copia de los datos necesarios y devuelve su resultado. Informa del progreso mediante IProgress<T>. Como el objeto Progress se creó en el hilo de la interfaz, cada aviso llega allí. El cálculo comprueba periódicamente la cancelación mediante el CancellationToken.
De la práctica: entre 12,5 y 15 veces más rápido
Una empresa había desarrollado su propio sistema CAD y lo había ampliado durante años con muchísimas funciones. Con diseños grandes había que esperar varios minutos a que hubiera una respuesta: el sistema estaba prácticamente congelado. El objetivo del cliente era duplicar la velocidad.
Analizamos el software y recogimos los puntos de mejora en un documento conceptual. Con casi 50 puntos dejamos de contar. Las medidas más eficaces las aplicamos nosotros mismos. Al departamento de software del cliente lo guiamos en varias reuniones para que aplicara por sí mismo los demás puntos. Los cálculos costosos se ejecutan ahora en segundo plano. El resultado: en lugar de la duplicación esperada, el sistema es entre 12,5 y 15 veces más rápido, medido en las versiones intermedias. Donde se calcula en segundo plano, los usuarios ya no notan ningún retraso.
Errores típicos
- Optimizar sin medir. Quien adivina suele mejorar puntos que apenas cuestan tiempo.
- Medir con datos de prueba pequeños. Muchos frenos solo aparecen con grandes cantidades de datos.
- Bloquearse esperando el resultado en lugar de esperarlo con await.
.Resulto.Wait()en el hilo de la interfaz vuelven a bloquear la interfaz y pueden provocar interbloqueos. async voidfuera de los controladores de eventos. Allí no se pueden capturar las excepciones. En los demás casos, utiliceasync Task.- Acceder desde segundo plano a la interfaz o a la base de datos CAD. Esto provoca bloqueos esporádicos difíciles de encontrar.
- No seguir comprobando tras la optimización. Sin mediciones repetidas ni pruebas automatizadas, el software vuelve a ralentizarse sin que nadie lo note con las siguientes versiones.
- Dejar el conocimiento en manos del proveedor de servicios. Si su equipo entiende por qué algo se ha vuelto más rápido, el software seguirá siendo rápido en el futuro.
Cómo le ayudamos
- Analizamos su software, recogemos los puntos de mejora en un documento conceptual y los aplicamos con usted: control de calidad y revisión de código.
- Aseguramos la velocidad alcanzada con pruebas automatizadas: automatización de pruebas.
- Todos los servicios en torno a un software estable y seguro: calidad y seguridad.
- ¿Su software se congela? Concierte una primera conversación.
Fuentes: caso de estudio «Sistema CAD propio: entre 12,5 y 15 veces más rápido», casos de estudio de Cadida; Microsoft Learn: programación asincrónica con async y await.
