Являются ли строки php неизменяемыми? - PullRequest
13 голосов
/ 30 января 2009

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

Ответы [ 5 ]

20 голосов
/ 30 января 2009

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

5 голосов
/ 03 августа 2011

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

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, заключается в том, что имеет смысл передавать строковые значения по ссылке.

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

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

<?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-реализация алгоритма конкатенации строк водораздела доступна. Тот же алгоритм может быть (был мной) обобщен для ускорения умножения произвольных целых чисел точности.

3 голосов
/ 30 января 2009

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

2 голосов
/ 10 апреля 2014

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

Пример:

$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   "
0 голосов
/ 05 августа 2013

Строки PHP являются неизменяемыми.

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

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

Это эхо:

string
bing
string

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...