En la gran mayoría de los casos, las mejoras en los algoritmos hacen una diferencia mayor que la mejora en la optimización. Los algoritmos también son más portátiles que las optimizaciones de bajo nivel. Mi consejo es seguir las mejores prácticas generales con respecto al diseño de la memoria para la reutilización de la memoria caché, evitar copias o comunicaciones excesivas, tratar el sistema de archivos de una manera sensata y hacer que los núcleos de punto flotante tengan suficiente granularidad para la vectorización. Algunas veces esto es suficiente para alcanzar una fracción aceptablemente alta de "pico" (para esta operación).
Siempre esboce un modelo de rendimiento para operaciones que considere importantes (o que descubra que son importantes mediante la creación de perfiles). Luego puede usar el modelo de rendimiento para estimar lo que podría ofrecer una implementación altamente ajustada. Si decide que la aceleración vale la pena (en relación con las otras cosas que podría estar haciendo), realice la optimización.
Quizás el desafío más difícil es diseñar interfaces de alto nivel e importantes (en el sentido de que mucho código dependerá de estas opciones) interfaces y estructuras de datos para que pueda optimizar más adelante sin necesidad de cambiar la API. A diferencia de las optimizaciones específicas y las pautas generales, no sé cómo enseñar esto, excepto a través de la experiencia. Trabajar con software de código abierto sensible al rendimiento ayuda. Como con cualquier decisión de API, es importante entender el espacio del problema.