PHP медленно работает при соединении строк? - PullRequest
1 голос
/ 28 ноября 2011

кажется, что php очень медленно обрабатывает большое количество строк, могу ли я в любом случае улучшить его скорость?код, который я пытался написать, превратит изображение в строку значений RGB для дальнейшего использования, это будет что-то вроде

$string = "255:255:253#12:12:23#33:34:24"/*an output of a $SIZE = 3 image*/

, проблема в том, что когда $ SIZE большой, как 256, потребуетсядо 1 секунды, чтобы получить строку

$r = "";
$g = "";
$b = "";

for($y = 0; $y <= $SIZE-1; $y++){
    for($x = 0; $x <= $SIZE-1; $x++){


        {$r .= $arr2[$y][$x]["R"].":";}

        {$g .= $arr2[$y][$x]["G"].":";}

        {$b .= $arr2[$y][$x]["B"].":";}

    }
}
$r = rtrim($r, ":");
$g = rtrim($g, ":");
$b = rtrim($b, ":");
$str_a .= $r."#".$g."#".$b;

Ответы [ 2 ]

6 голосов
/ 28 ноября 2011

Первое, что нужно иметь в виду, это то, что вы делаете действительно большое количество итераций.Если ваша переменная $ SIZE равна 256, то вы на самом деле делаете 256 X 256 (65536) итераций.Ваша самая большая надежда на ускорение цикла - найти способ сделать то, что вам нужно, за меньшее количество циклов.

Вы можете попытаться использовать массив для создания строки, которую вы хотите вывести, а затем развернуть (), когда закончите.Однако это будет микрооптимизация, и выигрыш в скорости, который вы получите, вероятно, не будет стоить усилий.Я бы посоветовал создать простой цикл тестирования, который можно сравнить, чтобы сравнить конкатенацию строк со сборкой и развертыванием массива.

4 голосов
/ 28 ноября 2011

На основе вашего кода мы можем перепроектировать структуру $ arr2 в (при условии, что R, G и B целые числа от 0 до 255):

$arr2 = array(
   0 => array(
      0 => array(
        "R" => 128,
        "G" => 64,
        "B" => 255
      ),
      1 => array(
        ...
      ) 
   )
);

Учитывая, что ваш $SIZEустановлен на 256, у вас будет в общей сложности 256*256=65536 массивов, дополнительно содержащих массивы со значениями ключей для R, G и B, в результате чего в общей сложности 256*256*3=196608 integers на 3 уровнях иерархии.Не удивительно, что ваш код работает медленно!

Я думаю, что лучшая стратегия здесь - попытаться уменьшить общее количество элементов в вашем массиве.

Учитывая, что вместо того, чтобы кодировать отдельные ячейки как тройки "R, G, B", вы можете кодировать все значения в одно целое число.Например, вместо:

0 => array( "R" => $r, "G" => $g, "B" => $b )

Учитывая, что 0<=r,g,b<=255, вы можете закодировать $arr2 как:

0 => ($r<<16 + $g<<8 + $b);

Теперь, конечно, вам нужно распаковать значение цвета внутри циклатакже.Это может быть достигнуто следующим образом:

$col = $arr2[$y][$x];
$col_b = ($col&255);
$col_g = ($col>>8)&255;
$col_r = ($col>>16)&255;
$r .= $col_r.":";
$g .= $col_g.":";
$b .= $col_b.":";

Одна только эта модификация полностью вырезает один уровень иерархии из вашего массива.

При выполнении исходного кода с $ SIZE = 256, моя средняя скорость выполненияв моих настройках было 0,30 сек. С помощью данного рефакторинга я смог сократить его до 0,10 с, сократив время вычисления до 1/3 от исходного.

Вам все равно придется много работать, если выЯ хочу улучшить производительность, но я надеюсь, что это даст вам представление о том, как вы могли бы действовать.

...