Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中优化指数移动平均算法?_Php_Algorithm_Optimization - Fatal编程技术网

如何在PHP中优化指数移动平均算法?

如何在PHP中优化指数移动平均算法?,php,algorithm,optimization,Php,Algorithm,Optimization,我试图检索一个大数据集(15000个以上的值)的最后一个EMA。这是一个非常消耗资源的算法,因为每个值都依赖于前一个值。这是我的密码: $k = 2/($range+1); for ($i; $i<$size_data; ++$i) { $lastEMA = $lastEMA + $k * ($data[$i]-$lastEMA); } $k=2/($range+1); 对于($i;$i构建自己的扩展肯定会提高性能 一些性能指标:硬件:Ubuntu 14.04、PHP5.5.9、

我试图检索一个大数据集(15000个以上的值)的最后一个EMA。这是一个非常消耗资源的算法,因为每个值都依赖于前一个值。这是我的密码:

$k = 2/($range+1);
for ($i; $i<$size_data; ++$i) {
    $lastEMA = $lastEMA + $k * ($data[$i]-$lastEMA);
}
$k=2/($range+1);

对于($i;$i构建自己的扩展肯定会提高性能

一些性能指标:硬件:Ubuntu 14.04、PHP5.5.9、单核英特尔CPU@3.3Ghz,128MB内存(这是一个VPS)

  • 之前(仅PHP,16000个值):500ms
  • C扩展,16000个值:0.3ms
  • C扩展(100000个值):3.7ms
  • C扩展(500000个值):28.0ms

但目前我的内存有限,使用70MB。我会解决这个问题并相应地更新数字。

显然,使用扩展实现会给您带来显著的提升。 此外,微积分本身可以改进,您可以选择任何一种语言进行添加

很容易看出,lastEMA的计算公式如下:

$lastEMA = 0;
$k = 2/($range+1);
for ($i; $i<$size_data; ++$i) {
    $lastEMA = (1-$k) * $lastEMA + $k * $data[$i];
}
因此,如果实现语言支持并行化,那么数据集可以划分为4个(或8个或n个…基本上是可用的CPU核数)块,并可以并行计算每个块上的项总和,最后将各个结果相加


我没有详细说明这一点,因为这个回答已经非常长了,我认为这个概念已经表达出来了。

数据集以什么方式变化?如果只是添加到数据集中,您能不能不存储最后的结果并计算新的值?或者整个数据集整体变化?当然,您可以编写自己的PHP扩展,并且可以访问您希望发送给它的任何PHP数据结构。@halfer数据集本身不会更改(上面代码中的变量$data)计算值为$lastEMA。我目前正在尝试编写自己的扩展,但我不知道正确与否。但如果数据集不会更改,可能至少会在某些情况下更改(例如,从一个用户到另一个用户),否则优化它就没有意义了。在这种情况下,你可以只计算一次均线并永久使用它!因此,我的根本问题是:你需要优化吗?如果需要,为什么?我认为$k可以改变…或者更好的是,反过来得到$k的$range。是这种情况吗?谢谢你!我在s上使用这个股票市场数据,因此旧数据与新数据在同一数量级上的事实取决于所使用的时间框架。假设200美元的范围,每天时间框架(200天)的价格变化将比5分钟时间框架(16小时)的价格变化大得多。我将在真实数据和模拟数据上试验不同的场景。在新数据上,在$range<200的情况下,我使用1000个元素的数据集。但在过去几年中,我也做了一些回测,因此我仍然需要加载整个数据集。在这两种情况下,您都提供了帮助,谢谢!
$lastEMA = 0;
$k = 2/($range+1);
$k1m = 1 - $k;
for ($i; $i<$size_data; ++$i) {
    $lastEMA = $k1m * $lastEMA + $data[$i];
}
$lastEMA = $lastEMA * $k;
$lastEMA = 0;
$k = 2/($range+1);
$k1m = 1 - $k;
for ($i; $i<$size_data; ++$i) {
    $lastEMA += $k1m ^ ($size_data - 1 - $i) *  $data[$i];
}
$lastEMA = $lastEMA * $k;