Строки php неизменяемы?

Или: Должен ли я оптимизировать свои строковые операции в PHP? Я попытался спросить руководство PHP об этом, но у меня не было никаких намеков на что-либо.

PHP уже оптимизирует его – переменные назначаются с помощью copy-on-write , а объекты передаются по ссылке. В PHP 4 это не так, но никто не должен использовать PHP 4 для нового кода.

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

1. Меньше экземпляров означает меньше времени на строительство.

2. Чем меньше объем памяти, используемой приложением, тем меньше ошибок в кэше процессора, вероятно, есть.

Для приложений, где скорость является приоритетом №1, существует действительно узкое узкое место между ЦП и ОЗУ. Одной из причин узкого места является латентность ОЗУ.

PHP, Ruby, Python и т. Д. Относятся к промахам кэш-памяти тем фактом, что даже они хранят хотя бы некоторые (возможно, все) данные времени выполнения интерпретируемых программ в ОЗУ.

Создание экземпляра строки является одной из операций, которые выполняются довольно часто, в относительно «огромных количествах», и это может иметь заметное влияние на скорость.

Вот экспериментальный эксперимент run_test.bash:

 #!/bin/bash for i in `seq 1 200`; do /usr/bin/time -p -a -o ./measuring_data.rb php5 ./string_instantiation_speedtest.php done 

Ниже приведены результаты ./string_instantiation_speedtest.php и результаты измерений:

 <?php // The comments on the // next 2 lines show arithmetic mean of (user time + sys time) for 200 runs. $b_instantiate=False; // 0.1624 seconds $b_instantiate=True; // 0.1676 seconds // The time consumed by the reference version is about 97% of the // time consumed by the instantiation version, but a thing to notice is // that the loop contains at least 1, probably 2, possibly 4, // string instantiations at the array_push line. $ar=array(); $s='This is a string.'; $n=10000; $s_1=NULL; for($i=0;$i<$n;$i++) { if($b_instantiate) { $s_1=''.$s; } else { $s_1=&$s; } // The rand is for avoiding optimization at storage. array_push($ar,''.rand(0,9).$s_1); } // for echo($ar[rand(0,$n)]."\n"); ?> 

Мой вывод из этого эксперимента и еще один эксперимент, который я сделал с Ruby 1.8, состоит в том, что имеет смысл передавать строковые значения вокруг ссылки.

Один из возможных способов разрешить «pass-strings-by-reference» для всей области приложения – последовательно создавать новый экземпляр строки, когда нужно использовать модифицированную версию строки.

Чтобы увеличить локальность, следовательно, скорость, можно уменьшить объем памяти, который потребляет каждый из операндов. Следующий эксперимент демонстрирует случай конкатенаций строк:

 <?php // The comments on the // next 2 lines show arithmetic mean of (user time + sys time) for 200 runs. $b_suboptimal=False; // 0.0611 seconds $b_suboptimal=True; // 0.0785 seconds // The time consumed by the optimal version is about 78% of the // time consumed by the suboptimal version. // // The number of concatenations is the same and the resultant // string is the same, but what differs is the "average" and maximum // lengths of the tokens that are used for assembling the $s_whole. $n=1000; $s_token="This is a string with a Linux line break.\n"; $s_whole=''; if($b_suboptimal) { for($i=0;$i<$n;$i++) { $s_whole=$s_whole.$s_token.$i; } // for } else { $i_watershed=(int)round((($n*1.0)/2),0); $s_part_1=''; $s_part_2=''; for($i=0;$i<$i_watershed;$i++) { $s_part_1=$s_part_1.$i.$s_token; } // for for($i=$i_watershed;$i<$n;$i++) { $s_part_2=$s_part_2.$i.$s_token; } // for $s_whole=$s_part_1.$s_part_2; } // else // To circumvent possible optimization one actually "uses" the // value of the $s_whole. $file_handle=fopen('./it_might_have_been_a_served_HTML_page.txt','w'); fwrite($file_handle, $s_whole); fclose($file_handle); ?> 

Например, если вы собираете HTML-страницы, содержащие значительное количество текста, тогда вам может понадобиться подумать о порядке, как различные части сгенерированного HTML будут объединены друг с другом.

Доступен BSD-лицензированная реализация PHP и реализация Ruby алгоритма конкатенации строк водораздела. Тот же алгоритм может быть (был мной) обобщен для ускорения умножения произвольных целых чисел точности.

Быстрый google, похоже, предположил бы, что они изменяемы, но предпочтительная практика – относиться к ним как к неизменяемым.

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

Пример:

 $a = array_fill(0, 10000, 42); //Consumes 545744 bytes $b = $a; // " 48 " $b[0] = 42; // " 545656 " $s = str_repeat(' ', 10000); // " 10096 " $t = $s; // " 48 " $t[0] = '!'; // " 10048 " 

Строки PHP неизменяемы.

Попробуй это:

  $a="string"; echo "<br>$a<br>"; echo str_replace('str','b',$a); echo "<br>$a"; 

Это эхо:

 string bing string 

Если строка была изменчивой, она продолжала бы показывать «bing».