数组中超过64万个元素 - 内存问题[Dijkstra]

时间:2011-02-01 20:39:37

标签: php memory limit dijkstra

我有一个脚本,它将803 * 803 (644 809)图表中的每个值分别设置为1 000 000。使用~500 * 500一切正常 - 但现在它崩溃了 - 它试图分配超过64MB的内存(我没有)。解决方案是什么?不知何故“拆分”或......?

$result=mysql_query("SELECT * FROM some_table", $connection);
confirm($result);
while($rows = mysql_fetch_array($result)){
    $result2=mysql_query("SELECT * FROM some_table", $connection);
    confirm($result2);
    while($rows2 = mysql_fetch_array($result2)){
        $first = $rows["something"];
        $second = $rows2["something2"];

        $graph[$first][$second] = 1000000;
    }
}

*它是关于Dijkstra算法

P.S。不,我不能分配超过64MB

4 个答案:

答案 0 :(得分:3)

尝试在每个循环结束时使用mysql_free_result($result2);释放内部sql结果,PHP脚本可能不会为您执行此操作,具体取决于PHP版本(垃圾收集器可能未启用或可能无用)由于PHP版本太旧了。)

不要在循环中实现两个临时变量,直接使用mysql_fetch_array结果,如$graph[$rows["something"]][$rows2["something2"]] = 1000000;,每个循环将节省2个内存分配..

PS:这是 micro - 优化,因此它可以帮助您节省足够的内存以适应您的64M内存。不要忘记,对于64 * 1024 * 1024字节的内存,每个644 809元素的最大大小平均为104字节,加上数组大小本身,以及您为算法分配的其余临时数据

如果它不合适,请考虑拆分矩阵并执行批量作业等,以便在较少的内存消耗中分割您的工作,但运行多个脚本。

答案 1 :(得分:1)

如果您的上述代码示例实际上与您的实际代码匹配,那么您将获取相同的结果两次(即使在循环中也是第二个)。如果它是相同的数据集,那么从数据库中获取一次就足够了,这将完全减少数据库负载,执行时间和内存占用。

也许以下方法可能会在您的内存限制环境中起作用。

$result = mysql_unbuffered_query("SELECT * FROM some_table", $connection);
confirm($result);
$rawData    = array();
while ($rows = mysql_fetch_assoc($result)) {
    $rawData[] = array($rows["something"], $rows["something2"]);
}
mysql_free_result($result);

$graph = array();
foreach ($rawData as $r1) {
    foreach ($rawData as $r2) {
        $graph[$r1[0]][$r2[1]] = 1000000;
    }
}
unset($rawData);

注意:

  • 我正在使用mysql_fetch_assoc()而不是mysql_fetch_array(),因为后者将每列返回两次(一个数字索引,一个按列名索引)
  • 使用mysql_unbuffered_query()代替mysql_query()也可能会减少内存占用量(取决于实际的数据集大小)

答案 2 :(得分:0)

尝试使用http://en.wikipedia.org/wiki/Adjacency_list来表示图形而不是邻接矩阵(我认为您使用的是$graph[$first][$second] = 1000000;

的矩阵原因

对于稀疏图形,它占用的内存较少。

答案 3 :(得分:0)

如果你坚持使用PHP进行高内存操作(开始时这不是一个好主意),我会将图形划分为象限,并使用GD来组合象限。这样,您只需构建内存占用量为1/4的图形。

同样,这并不理想,但你正试图用钉子钉锤子:D