Algunas sugerencias ordenadas por “mejora potencial con el tiempo que necesita invertir”:
- Tenga en cuenta cómo se implementan varias operaciones integradas y tipos de datos en el idioma que elija. Puede resultar que algo que pensabas toma tiempo constante, en realidad toma mucho más tiempo. Entonces puedes optimizarlo.
Ejemplos: operaciones en cadenas y matrices, como su tamaño, tomar una porción o incluso encontrar el enésimo elemento (en una cadena unicode). - Localidad de la memoria: tenga en cuenta cómo funcionan la memoria virtual y el caché de la CPU.
Todos los datos que su programa está procesando en algún momento deben llevarse a (a) memoria física y (b) caché de la CPU. Cuanto más se dispersan, más operaciones de intercambio / intercambio se necesitan y su programa efectivamente necesita mucho más tiempo para acceder a la memoria.
Puede verificar las estadísticas del sistema para ver si su programa está entrando y saliendo (memoria virtual). Si hay suficiente RAM, eso no debería ser un problema. Pero exactamente el mismo mecanismo funciona en una escala menor en el nivel de caché de la CPU.
Ejemplo : resumir todos los elementos en una matriz de números. - La peor solución: la matriz se almacena como una lista vinculada de listas vinculadas de registros que pueden dispersarse arbitrariamente en la memoria. En primer lugar, usas mucha memoria. En segundo lugar, los elementos consecutivos a los que se accede no tienen que estar cerca uno del otro.
- Mejor solución: matriz 2D de números, iterar sobre “columnas” agregando todos los elementos en una columna. Se utiliza menos memoria, pero los números consecutivos a los que se accede están lejos el uno del otro y el caché de la CPU realiza más intercambios.
- La mejor solución: matriz 2D de números, iterar sobre “filas” agregando todos los elementos en una fila. Los números consecutivos a los que se accede están uno al lado del otro, lo que minimiza el intercambio, tanto para el caché de la CPU como para la memoria virtual.
- Haga que su programa sea paralelo y use todos los núcleos de CPU que tenga.
Las CPU no serán mucho más rápidas en el futuro. Por un lado, la información no puede viajar más rápido que la luz (para un reloj de 3 GHz es de 10 cm). Por otro lado, los transistores no pueden ser infinitamente pequeños, ya que están hechos de átomos.
Por lo tanto, es más fácil poner más núcleos de CPU que se ejecutan en paralelo.
Para hacer uso de ese poder, debe reescribir su algoritmo para que se ejecute simultáneamente varios hilos. Es difícil. Un problema es repensar su algoritmo. Otra es sincronizar los hilos que operan en una estructura de datos común. Pero la parte más difícil es asegurarse de que su programa sea correcto. En la programación concurrente, las pruebas no ayudan mucho, ya que no verifica todas las formas posibles en que los hilos pueden intercalar su ejecución.