Esto es solo para satisfacer mi propia curiosidad.¿Es posible escribir la función InvSqrt() rápida de Quake en C#?
¿Existe una implementación de este:
float InvSqrt (float x)
{
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i>>1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}
en C#? Si existe, publique el código.
Supongo que debería haber mencionado que estaba buscando una implementación "segura" ... En cualquier caso, el código BitConverter resuelve el problema. La idea de unión es interesante. Lo probaré y publicaré mis resultados.
Edit: Como era de esperar, el método inseguro es el más rápido, seguido por el uso de una unión (dentro de la función), seguido por el BitConverter. Las funciones se ejecutaron 10000000 veces, y utilicé la clase System.Diagnostics.Stopwatch para medir el tiempo. Los resultados de los cálculos se muestran entre paréntesis.
Input: 79.67
BitConverter Method: 00:00:01.2809018 (0.1120187)
Union Method: 00:00:00.6838758 (0.1120187)
Unsafe Method: 00:00:00.3376401 (0.1120187)
Para completar, he probado el método integrado Math.pow, y el método "naive" (1/sqrt (x)).
Math.Pow(x, -0.5): 00:00:01.7133228 (0.112034710535584)
1/Math.Sqrt(x): 00:00:00.3757084 (0.1120347)
La diferencia entre 1/Math.Sqrt() es tan pequeño que no creo que uno tiene que recurrir al método inseguro InvSqrt rápido() en C# (o cualquier otro método inseguro). A menos que uno realmente necesite exprimir el último bit de jugo de la CPU ... 1/Math.Sqrt() también es mucho más preciso.
Para completar, debe ejecutar una prueba usando "1/math.Sqrt()" también. –
Lo hice, y otro escenario. Actualizaré los puntos de referencia tan pronto como pueda verificar los resultados. – ilitirit
Creo que deberías haber hecho tus pruebas con un set más grande, para que tuvieran unos segundos en completarse. – Gleno