Muy a menudo, la mejor manera de ganar rendimiento es cambiar su algoritmo. Cuanto menos general sea la implementación, más cerca podrá llegar al metal.
Suponiendo que se haya hecho ...
Si realmente es un código crítico, trate de evitar lecturas de memoria, trate de evitar calcular cosas que puedan calcularse previamente (aunque no hay tablas de búsqueda ya que violan la regla número 1). Sepa lo que hace su algoritmo y escríbalo de una manera que el compilador también lo sepa. Verifique el ensamblaje para asegurarse de que lo haga.
Evite los errores de caché. Procese por lotes tanto como pueda. Evite funciones virtuales y otras indirecciones.
En definitiva, medir todo. Las reglas cambian todo el tiempo. Lo que solía acelerar el código hace 3 años ahora lo ralentiza. Un buen ejemplo es 'usar funciones matemáticas dobles en lugar de versiones flotantes'. No me habría dado cuenta de eso si no lo hubiera leído.
Lo olvidé: no los constructores predeterminados inicializan sus variables, o si insiste, al menos también cree constructores que no. Tenga en cuenta las cosas que no aparecen en los perfiles. Cuando pierde un ciclo innecesario por línea de código, no aparecerá nada en su generador de perfiles, pero perderá muchos ciclos en general. Nuevamente, sepa lo que está haciendo su código. Haga que su función principal sea delgada en lugar de infalible. Se pueden llamar versiones infalibles si es necesario, pero no siempre se necesitan. La versatilidad tiene un precio: el rendimiento es uno.
Editado para explicar por qué no hay inicialización predeterminada: una gran cantidad de código dice: Vector3 bla; bla = DoSomething ();
La inicialización en el constructor es tiempo perdido. Además, en este caso el tiempo perdido es pequeño (probablemente borrando el vector), sin embargo, si sus programadores hacen esto habitualmente, se acumula. Además, muchas funciones crean un temporal (piense en operadores sobrecargados), que se inicializa a cero y se asigna inmediatamente. Ciclos perdidos ocultos que son demasiado pequeños para ver un pico en su generador de perfiles, pero sangran ciclos en toda su base de código. Además, algunas personas hacen mucho más en constructores (que obviamente es un no-no). He visto ganancias de varios milisegundos de una variable no utilizada donde el constructor resultó ser un poco pesado. Tan pronto como el constructor cause efectos secundarios, el compilador no podrá desactivarlo, por lo que, a menos que nunca use el código anterior, prefiero un constructor que no se inicialice o, como dije,
Vector3 bla (noInit); bla = hacer algo ();