PHP的substr效率如何?

时间:2010-05-11 17:51:30

标签: php optimization memory-management substr

我正在用PHP编写一个解析器,它必须能够处理大型内存中的字符串,所以这是一个有点重要的问题。 (即,请不要“过早优化”火焰我,请)

substr功能如何运作?它是否在内存中生成字符串数据的第二个副本,还是引用原始数据?我是否应该担心在循环中调用$str = substr($str, 1);

3 个答案:

答案 0 :(得分:4)

如果你真的在研究效率,你需要用你的字符串保留一个指针 - 我的意思是 index 。许多字符串函数接受一个偏移量来开始操作(如strpos()的第三个参数)。通常我会建议编写一个对象来包装这个功能,但如果你期望使用它很多,那么可能会导致性能瓶颈。这是我的意思的一个例子(没有OO):

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
    # ...
}

答案 1 :(得分:3)

为了进一步发表Chad的评论,你的代码需要两个字符串(完整的字符串和完整的一个减去第一个字符)同时在内存中(尽管不是由于Chad所说的分配) 。参见:

$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  :-(

答案 2 :(得分:1)

是的,你应该小心在循环中进行任何字符串操作,因为每次迭代都会生成字符串的新副本。