0

我有这段代码执行用 php 编写的矩阵向量乘法。

这是一个片段:

for($i = 0; $i < sizeof($transposed_matrix); $i++) {
            $vector[$i] = 0;
            for($j = 0; $j < sizeof($new_vector); $j++) {
                $vector[$i] += ($transposed_matrix[$i][$j] * $new_vector[$j]);
            }
        }

我想知道是否有任何方法可以使这段代码运行得更快?

4

3 回答 3

0

PHP 数组有变慢的趋势,这是对散列机制的致敬。PHP 数组性能。如果您有办法预先确定向量的大小,则可以展开循环并避免使用数组。如果您的代码是整个代码,那么这对您没有帮助,因为其中的每个项目$transposed_matrix只被点击一次,您可以$vector使用$sumAtze Kaputnik 概述的技术来减少点击次数。因此,您最终会将数组参数中的内容复制到局部变量,然后进行计算,然后再复制回来……这不仅会扼杀性能提升。

最后,您所能做的就是切换到一种完全不同的优化方法:JIT 编译器,如HipHop或编译语言。C 中的相同循环可能会以 10 到 100 倍的速度运行,减去分叉该进程的时间。

于 2013-02-28T00:00:25.140 回答
0

一种优化是在之前计算for

$size = sizeof($transposed_matrix);
$size2 = sizeof($new_vector);
for($i = 0; $i < $size; $i++) {
    $vector[$i] = 0;        
    for($j = 0; $j < $size2; $j++) {
        $vector[$i] += ($transposed_matrix[$i][$j] * $new_vector[$j]);
    }
}
于 2013-02-27T10:20:33.497 回答
0

PHP 没有给你足够的控制来进行一些严重的优化。提议的改进可能会产生相对较小的影响,除非您将巨大的矩阵和向量相乘(在这种情况下,您首先不应该使用 PHP)。

除了预先计算大小并为计数器使用预增量(如 Tjoene 所建议的那样),在内部循环中使用一个临时变量作为总和,如下所示:

$sum = 0;
for ($j = 0; $j < $numCols; ++$j) {
    $sum += $matrix[$i][$j] * $vector[$j];
}
$vector[$i] = $sum;

这将避免在 $vector 中多次计算正确的目标位置。

通过将矩阵数据存储在单个平面数组中而不是您使用的嵌套结构中,可能可以获得最大的性能增益。只需连接矩阵的行,您就可以使用单个索引遍历其元素,如下所示:

for ($i = 0, $n = 0; $i < $numRows; ++$i, ++$n)
{
    $sum = 0;
    for ($j = 0; $j < $numCols; ++$j) {
        $sum += $matrix[$n] * $vector[$j];
    }
    $vector[$i] = $sum;
}

当然,如果您不必在实际乘法之前转换为此矩阵布局,这只会加快速度。

如果您不想更改矩阵布局,则可以通过foreach在外部循环中使用来检索矩阵的行来加快速度。但是请注意,这会按照将这些行数组添加到矩阵的顺序遍历行集!如果矩阵和向量之间的顺序不同,结果将全是错误的。所以,可能不是那么可靠的事情,因为它很容易打破......

哦,你总是可以尝试部分展开循环。

于 2013-02-27T23:28:07.550 回答