2

それぞれに1000000の値を持つ803*803 (644 809)グラフを配置するスクリプトがあります。〜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;
    }
}

*それはダイクストラアルゴリズムについてです

psいいえ、64MBを超えて割り当てることはできません

4

4 に答える 4

3

を使用して、各ループの最後に内部SQL結果を解放してみてください。PHPのmysql_free_result($result2);バージョンによっては、PHPスクリプトがそれを実行しない場合があります(ガベージコレクターが有効になっていないか、PHPバージョンが古すぎるために役に立たない場合があります) 。

ループ内で2つの一時変数をインスタンス化しないでください。たとえば、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

上記のコードサンプルが実際に実際のコードと一致する場合、同じ結果を2回フェッチしています(2回目はループ内でも)。同じデータセットの場合、データベースから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()は、後者がすべての列を2回返すためです(1つは数値でインデックス付けされ、もう1つは列名でインデックス付けされます)
  • おそらく、mysql_unbuffered_query()代わりにを使用するとmysql_query()、メモリフットプリントも削減される可能性があります(実際のデータセットサイズによって異なります)
于 2011-02-02T08:27:15.527 に答える
0

隣接行列の代わりに http://en.wikipedia.org/wiki/Adjacency_listを使用してグラフを表現してみてください($graph[$first][$second] = 1000000;

スパースグラフの場合、必要なメモリは少なくなります。

于 2011-02-01T20:46:00.457 に答える
0

高メモリ操作にPHPを使用することを主張する場合(最初はあまり良い考えではありません)、グラフを象限に分割し、GDを使用して象限を結合します。そうすれば、メモリフットプリントの1/4でグラフを作成するだけで済みます。

繰り返しますが、これは理想的ではありませんが、釘を使ってハンマーで打ち込もうとしています:D

于 2011-02-01T20:54:47.760 に答える