Tengo el siguiente código haciendo la función Sin/Cos usando una tabla de memoria precalculada. en el siguiente ejemplo, la tabla tiene 1024 * 128 ítems que cubren todos los valores Sin/Cos de 0 a 2pi. Sé que puedo usar la simetría Sin/Cos y mantener solo 1/4 de los valores, pero tendré más 'si' al calcular el valor.Fast Sin/Cos utilizando una matriz de traducción calculada previamente
private const double PI2 = Math.PI * 2.0;
private const int TABLE_SIZE = 1024 * 128;
private const double TABLE_SIZE_D = (double)TABLE_SIZE;
private const double FACTOR = TABLE_SIZE_D/PI2;
private static double[] _CosineDoubleTable;
private static double[] _SineDoubleTable;
Establecer la tabla de traducción
private static void InitializeTrigonometricTables(){
_CosineDoubleTable = new double[TABLE_SIZE];
_SineDoubleTable = new double[TABLE_SIZE];
for (int i = 0; i < TABLE_SIZE; i++){
double Angle = ((double)i/TABLE_SIZE_D) * PI2;
_SineDoubleTable[i] = Math.Sin(Angle);
_CosineDoubleTable[i] = Math.Cos(Angle);
}
}
El valor es un doble en radianes.
Value %= PI2; // In case that the angle is larger than 2pi
if (Value < 0) Value += PI2; // in case that the angle is negative
int index = (int)(Value * FACTOR); //from radians to index and casted in to an int
double sineValue = _SineDoubleTable[index]; // get the value from the table
Estoy buscando una forma más rápida de hacerlo. Las 4 líneas anteriores son ~ 25% del proceso completo (ejecutadas miles de millones de veces).
¿Ha realizado una evaluación comparativa para ver si esta precomputación en realidad mejora el rendimiento? –
+1 por tener un problema tan ridículamente único. – grenade
¿Es posible cambiar el punto de optimización al código que llama a su búsqueda trigonométrica? Por ejemplo, volver a ordenar los datos de entrada para que pueda aprovechar el almacenamiento en caché de los valores Sin/Cos calculados. – LBushkin