2

我有一个脚本,其中放置了 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 算法的

ps 不,我不能分配超过 64MB

4

4 回答 4

3

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

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

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

如果它不适合,请考虑拆分您的矩阵并执行批处理作业等,以便将您的工作拆分为占用较少内存但运行多个脚本的工作。

于 2011-02-01T20:54:00.930 回答
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()可能减少内存占用(取决于实际数据集大小)
于 2011-02-02T08:27:15.527 回答
0

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

同样,这并不理想,但是您正在尝试使用钉子敲击锤子:D

于 2011-02-01T20:54:47.760 回答
0

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

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

于 2011-02-01T20:46:00.457 回答