Насколько эффективный substr PHP?

Я пишу синтаксический анализатор в PHP, который должен смочь обработать большие строки в оперативной памяти, таким образом, это - несколько важная проблема. (т.е., не делайте "преждевременный, оптимизируют" пламя меня),

Как делает substr функциональная работа? Это делает вторую копию строковых данных в памяти, или действительно ли это ссылается на оригинал? Если я волнуюсь о вызове, например, $str = substr($str, 1); в цикле?

7
задан zildjohn01 11 May 2010 в 17:51
поделиться

3 ответа

В продолжение комментария Чада, ваш код требует, чтобы обе строки (полная и полная минус первый символ) находились в памяти одновременно (хотя и не из-за присваивания, как указал Чад). Смотрите:

$string = str_repeat('x', 1048576);
printf("MEM:  %d\nPEAK: %d\n", memory_get_usage(), memory_get_peak_usage());

substr($string, 1);
printf("MEM:  %d\nPEAK: %d  :-(\n", memory_get_usage(), memory_get_peak_usage());

$string = substr($string, 1);
printf("MEM:  %d\nPEAK: %d  :-(\n", memory_get_usage(), memory_get_peak_usage());

Выходит что-то вроде (значения памяти в байтах):

MEM:  1093256
PEAK: 1093488
MEM:  1093280
PEAK: 2142116  :-(
MEM:  1093276
PEAK: 2142116  :-(
3
ответ дан 7 December 2019 в 05:18
поделиться

Если вы действительно хотите повысить эффективность, вам нужно будет сохранить указатель - я имею в виду index - с вашей строкой. Многие строковые функции принимают смещение для начала работы (например, третий параметр strpos () ). Обычно я бы рекомендовал написать объект для обертывания этой функциональности, но если вы планируете использовать это часто, это может вызвать узкое место в производительности. Вот пример того, что я имею в виду (без объектно-ориентированного подхода):

while ($whatever) {
    $pos = strpos($string, $myToken, $startIndex);
    # do something using $pos
    $startIndex = $pos;
}

Если хотите, вы можете написать свой собственный класс-оболочку, который выполняет эти строковые операции и посмотреть, влияет ли это на скорость:

class _String {
    private $string;
    private $startIndex;
    private $length;
    public function __construct($string) {
        $this->string = $string;
        $this->startIndex = 0;
        $this->length = strlen($string);
    }
    public function substr($from, $length = NULL) {
        $this->startIndex = $from;
        if ($length !== NULL) {
            $this->endIndex = $from + $length;
        }
    }
    # other functions you might use
    # ...
}
4
ответ дан 7 December 2019 в 05:18
поделиться

Да, вы должны быть осторожны, выполняя любые манипуляции со строкой внутри цикла, поскольку на каждой итерации будут создаваться новые копии строки.

1
ответ дан 7 December 2019 в 05:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: