Estoy tratando de recuperar la última EMA de un gran conjunto de datos (15000 valores). Es un algoritmo muy hambriento de recursos ya que cada valor depende de la anterior. Aquí está mi código: Lo que ya he hecho: Aislar k por lo que no se calcula 10000 veces Mantener sólo la última EMA calculado, y no mantener todos ellos en un uso de matriz para () en lugar de foreach () la matriz de datos no tiene claves Su matriz básica Esto me permitió reducir el tiempo de ejecución de 2000ms a cerca de 500ms para 15000 valores Lo que no funcionó: Use SplFixedArray (), esto afeitado sólo 10ms ejecutando 1.000.000 de valores Utilice la extensión PHPTrader. Esto devuelve una matriz que contiene todos los EMAs en lugar de sólo la última, y su más lento Escribir y ejecutar el mismo algoritmo en C y ejecutarlo más de 2.000.000 de valores toma sólo 13ms Así que obviamente, utilizando un compilado, ¿Debo ir de aquí El código en última instancia funcionará en Ubuntu, por lo que el idioma que debo elegir Will PHP ser capaz de llamar y pasar un argumento tan grande a la secuencia de comandos preguntó Jul 11 14 at 19:21 Claramente la aplicación con una extensión le da un Importante impulso. Además el cálculo se puede mejorar como sí mismo y que la ganancia se puede agregar en el idioma que elija. Es fácil ver que lastEMA se puede calcular como sigue: Esto se puede reescribir como sigue para sacar del lazo lo más posible: Para explicar la extracción del k piense que en la formulación anterior es como si toda la Los datos crudos originales se multiplican por k, así que prácticamente puede multiplicar el resultado final. Tenga en cuenta que, reescrito de esta manera, tiene 2 operaciones dentro del bucle en lugar de 3 (para ser precisos dentro del bucle también hay i incremento, i comparación con sizeata y asignación de valor lastEMA) de esta manera usted puede esperar para lograr un adicional Speedup en el rango entre los 16 y 33. Además hay otras mejoras que se pueden considerar al menos en algunas circunstancias: Considere sólo los últimos valores Los primeros valores se multiplican varias veces por k1m 1 - k por lo que su contribución puede ser poco o incluso ir Bajo la precisión de punto flotante (o el error aceptable). Esta idea es particularmente útil si se puede hacer la suposición de que los datos antiguos son del mismo orden de magnitud que los nuevos, porque si consideramos sólo los últimos n valores, el error que comete es err EMAofdiscardeddata (1-k) n. Así que si el orden de magnitud es ampliamente el mismo podemos decir que el error relativo hecho es relerr err / lastEMA EMA de los datos descodificados (1-k) n / lastEMA que es casi igual a (1-k) n. Bajo la suposición de que lastEMA es casi igual a EMAofdiscardeddata: Digamos que se puede aceptar un relerr de error relativo que se puede considerar con seguridad sólo los últimos n valores donde (1 - k) n lt relerr. Significa que se puede calcular previamente (antes del bucle) n log (relerr) / log (1-k) y calcular todo sólo considerando los últimos n valores. Si el conjunto de datos es muy grande esto puede dar una aceleración sensata. Tenga en cuenta que para números de punto flotante de 64 bits tiene una precisión relativa (relacionada con la mantisa) que es 2-53 (aproximadamente 1.1e-16 y sólo 2-24 5.96e-8 para números de punto flotante de 32 bits), por lo que no puede obtener Mejor que este error relativo por lo que básicamente nunca debe tener una ventaja en el cálculo de más de n log (1.1e-16) / log (1-k) valores. Para dar un ejemplo si rango 2000 entonces n log (1.1e-16) / log (1-2 / 2001) 36746. Creo que es interesante saber que los cálculos adicionales se perderían dentro de los redondeos es inútil es mejor no hacer. Ahora un ejemplo para el caso en el que puede aceptar un error relativo mayor que la coma flotante de precisión relerr 1ppm 1e-6 0.00001 6 dígitos decimales significativos que tiene n log (1.1e-16) / log (1-2 / 2001) 13815 Creo Es un número bastante pequeño en comparación con sus últimos números de muestras por lo que en los casos de la aceleración podría ser evidente (Im suponiendo que el rango de 2000 es significativo o alto para su aplicación, pero thi no puedo saber). Sólo otros pocos números porque no sé cuáles son sus figuras típicas: relerr 1e-3 rango 2000 n 6907 relerr 1e-3 rango 200 n 691 relerr 1e-3 rango 20 n 69 relerr 1e-6 rango 2000 n 13815 relerr 1e - 6 rango 200 n 1381 relerr 1e-6 rango 20 n 138 Si la asunción lastEMA casi igual a EMAofdiscardeddata no se puede tomar las cosas son menos fáciles, pero como la ventaja cam es significativa puede ser significativo para seguir: tenemos que volver a considerar la La fórmula completa: relerr EMAofdiscardeddata (1-k) n / lastEMA para n log (relerr lastEMA / EMAofdiscardeddata) / log (1-k) (log (relerr) log (lastEMA / EMAofdiscardeddata) Un caso es cuando sabemos a priori que, por ejemplo, EMA dediscardeddata / lastEMA lt M (por ejemplo, M 1000 o M 1e6) en ese caso n lt (log) es un cálculo de lastEMA / EMAofdiscardeddata (sin calcular realmente lastEMA ni EMAofdiscardeddata) (Relerr / M)) / log (1-k) si no puedes dar ningún número M tienes que encontrar una buena idea para sobreestimar EMAofdiscardeddata / lastEMA una forma rápida podría ser tomar M max (data) / min ) Paralelización El cálculo se puede volver a escribir en una forma en la que es una simple adición de términos independientes: Así que si el lenguaje de implementación soporta la paralelización, el conjunto de datos se puede dividir en 4 (o 8 o n. Básicamente el número de núcleos de CPU disponibles) y se puede calcular la suma de términos en cada trozo en paralelo, sumando los resultados individuales al final. No voy en detalle con esto ya que esta respuesta ya es terriblemente larga y creo que el concepto ya está expresado. Gracias por este I39m utilizando esto en los datos del mercado de valores, por lo que el hecho de que los datos más antiguos están en el mismo orden de magnitud que los nuevos datos depende del marco de tiempo utilizado. Supongamos que en un rango de 200, habrá una variación mucho mayor en los precios en un marco de tiempo diario (200 días) que 5 minutos (16 horas). Voy a experimentar con diferentes escenarios en datos reales y simulados. En los datos nuevos, con un rango lt 200, utilizo un conjunto de datos de 1000 elementos. Pero también hago algunas pruebas de nuevo en los últimos años, así que todavía necesito cargar el dataset entero. Usted ayudó en ambas situaciones, gracias ndash Lykegenes Jul 16 14 at 15:11 Construir su propia extensión sin duda mejora el rendimiento. Heres un buen tutorial de la página web de Zend. Algunas cifras de rendimiento: Hardware: Ubuntu 14.04, PHP 5.5.9, 1-core Intel CPU3.3Ghz, 128MB de RAM (es un VPS). Antes (sólo PHP, 16.000 valores). 500ms C Extensión, 16.000 valores. Extensión de 0,3 ms C (100,000 valores). 3.7ms C Extensión (500.000 valores). 28.0ms Pero Im memoria limitada en este momento, utilizando 70MB. Voy a fijar eso y actualizar los números en consecuencia. Quiero calcular el EMA (Exponential Moving Average) valor en PHP. Ive intentado con el código siguiente pero su darme 500 error. PHP: Función de cálculo de EMA trader-ema Tratado con mucho tiempo en Google, pero no recibiendo ninguna ayuda sobre esto en PHP. Por lo tanto, no tengo ni idea de lo que hay que hacer para calcular el valor EMA. Edit-1: Extensiones instaladas He instalado todas las extensiones necesarias, Ahora estoy recibiendo la salida. Pero no parece dar salida adecuada. Creo que la función de PHP para calcular EMA no está funcionando correctamente. Cualquier ayuda en esto sería muy apreciada. traderema la función traderema () no funciona correctamente. Calcula sólo el promedio de las entradas del último período. Siga el siguiente código para la función traderema: EMACalculator (limit, array) EMApreviousday array0 // printr (matriz) multiplier1 (2 / limit1) EMAarray () EMA array0 Cierra array1 while (limit) // echoEMA es EMAn EMA (Close - EMApreviousday) Multiplicador1 EMApreviousday EMApreviousday EMA limit-- devuelve EMA donde limit acepta el periodo de ema y array. Aceptar la matriz de datos para el cálculo de ema.
Comments
Post a Comment