1

このコードは 0.8 秒で実行され、私のマシンでは 22Mb のメモリを消費します。

   $x=500;
   $y=500;

   $im = imagecreatetruecolor($x,$y);
   $ia=array();
   for ($i = 0; $i < $x; $i++) {
    for ($j = 0; $j < $y; $j++) {
        $r=rand(0,96);
        $g=rand(0,128);
        $b=rand(0,255);
        $ia[$i][$j]=ImageColorAllocate($im,$r,$g,$b);
    }
   }

高速化するために何ができるか、さらに重要なのは、いつでも消費するメモリフットプリントを下げることです.

4

4 に答える 4

3

あなたの関数は、合計で 25 万回の反復を実行しています。これは常に、実行する PHP スクリプトのかなりの量になります。

ただし、できることがあります。

まず、mt_rand() は rand() より高速です。代わりにそれを使用してください。

次に、内側のループでループ展開を使用すると、速度が向上する可能性があります。それが実際にPHPでどれほど効果的かはわかりませんが、ベンチマークを行って効果を確認できます。

for ($j=0;$j<$y;$j+=10) {
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 1]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 2]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 3]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 4]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 5]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 6]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 7]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 8]=ImageColorAllocate($im,$r,$g,$b);
    $r=mt_rand(0,96);
    $g=mt_rand(0,128);
    $b=mt_rand(0,255);
    $ia[$i][$j + 9]=ImageColorAllocate($im,$r,$g,$b);
}

ただし、構築しているデータ構造は基本的に大きなものであるため、どちらもメモリフットプリントを削減しません。

この問題を間違った方向から見ているのではないでしょうか? ここで最初に自問すべきことは、やりたいことを達成するために、これほど巨大なデータ構造が本当に必要なのかということです。ループのアンロールとより高速な乱数ジェネレーターの使用により、パフォーマンスがいくらか向上しますが、最終的に最も高速なコードは、作成していないコードになります。特定のアルゴリズムのパフォーマンスにおける最大の要因は、常にアルゴリズムの選択です。何をしたいのかを再考すると、コンピューターのメモリと処理リソースの浪費がはるかに少ないものを思い付くかもしれません。

于 2011-04-30T16:09:54.297 に答える
2

直接色を割り当てる代わりに、次のコード ( http://php.net/manual/en/function.imagecolorallocate.phpから) を試してください。

function createcolor($pic,$c1,$c2,$c3) {
   $color = imagecolorexact($pic, $c1, $c2, $c3);
   if($color==-1) {
      if(imagecolorstotal($pic)>=1000) {
         $color = imagecolorclosest($pic, $c1, $c2, $c3);
      } else {
         $color = imagecolorallocate($pic, $c1, $c2, $c3);
      }
   }
   return $color;
 }

また、関数呼び出しを 1 行で実行してみてください。

$ia[$i][$j] = createcolor($im, mt_rand(0,96), mt_rand(0,128), mt_rand(0,255));

ハードコーディングされた値 1000 をいじって、メモリ使用量がどのように変化するかを確認します。

于 2011-04-30T16:37:17.063 に答える
1

私が知る限り、おそらくimagecreatetruecolorがメモリを浪費している可能性が最も高いようです。

のような別の方法を使用imagecreateして、代わりにイメージを作成できますか?

于 2011-04-30T16:12:40.727 に答える
1

コードで確認できる唯一の改善点は、同じ色を複数回割り当てないことです (この場合、ピクセル3.203.328の色)。これにより、メモリのフットプリント削減されます。500.000

$x = 500;
$y = 500;

$image = ImageCreateTrueColor($x, $y);
$matrix = array();
$colors = array();

for ($i = 0; $i < $x; $i++)
{
    for ($j = 0; $j < $y; $j++)
    {
        $rand = array(rand(0, 96), rand(0, 128), rand(0, 255));

        if (isset($colors[implode('|', $rand)]) !== true)
        {
            $colors[implode('|', $rand)] = ImageColorAllocate($im, $rand[0], $rand[1], $rand[2]);
        }

        $ia[$i][$j] = $colors[implode('|', $rand)];
    }
}

また、トゥルーカラー画像ImageCreate()が必要ない場合は、メモリをあまり消費しないはずです。


何をアーカイブしようとしているのかはわかりませんが、代わりに次の方法を使用する方がよいでしょう。mt_rand()

ランド() mt_rand()

于 2011-04-30T18:20:44.357 に答える