代码处理时间过长,占用内存很大

时间:2011-04-30 15:55:12

标签: php algorithm memory-management gd spl

此代码在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 个答案:

答案 0 :(得分: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);
}

但是,这些都不会减少内存占用,因为您构建的数据结构基本上是一个很大的数据结构。

也许你是从错误的方向看这个问题?你应该在这里问自己的第一件事是,你真的需要这么大的数据结构来完成你想做的事情吗?循环展开和使用更快的随机数生成器将为您带来一些性能提升,但最终您可以拥有的最快代码是您不编写的代码。任何给定算法的性能最大因素始终是算法的选择。如果你重新考虑你想做什么,你可能会想出一些不那么浪费你的计算机内存和处理资源的东西。

答案 1 :(得分: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,并查看它如何更改内存使用情况。

答案 2 :(得分:1)

据我所知,似乎imagecreatetruecolor可能是最可能成为记忆猪的罪魁祸首。

您可以使用其他方法(例如imagecreate)来创建图片吗?

答案 3 :(得分: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()应该减少记忆力。


我不确定您要归档的是什么,但可能会改为you would be better with mt_rand()

rand() mt_rand()