gpt4 book ai didi

php - 如何使 PHP 更快 : Does String Creation Have No Cost?

转载 作者:可可西里 更新时间:2023-11-01 00:04:28 24 4
gpt4 key购买 nike

this question提供了一个代码位,提问者希望通过消除变量的使用来使其更快。在我看来他找错地方了,但我绝不会知道。这是代码

while ($item = current($data))
{
echo '<ATTR>',$item, '</ATTR>', "\n";
next($data);
}

在我看来,字符串的重新创建 <ATTR>等等——每行不止一次,每次处理该行——都会有与之相关的成本(在速度和内存方面)。或者也许 PHP 处理器足够聪明,以至于在循环之前不将字符串放入变量中不会受到任何惩罚?

我在任何情况下都使用变量来明确和集中化,但是:使用变量、不使用变量或其他相关的成本是否存在?(任何想回答其他问题的人类似的语言请随意。)

最佳答案

如果你真的想用这种方式进行微优化(顺便说一句,我不认为它是相关的或有用的——但我知道它很有趣 ^^),你可以看看一个名为 Vulcan Logic Disassembler

它允许您获取为 PHP 脚本生成的字节码。

然后,您必须在命令行中使用类似这样的命令来启动脚本:

php -dextension=vld.so -dvld.active=1 tests/temp/temp.php

例如,使用这个脚本:

$data = array('a', 'b', 'c', 'd');
while ($item = current($data))
{
echo '<ATTR>',$item, '</ATTR>', "\n";
next($data);
}

你会得到这个字节码转储:

line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
8 0 EXT_STMT
1 INIT_ARRAY ~0 'a'
2 ADD_ARRAY_ELEMENT ~0 'b'
3 ADD_ARRAY_ELEMENT ~0 'c'
4 ADD_ARRAY_ELEMENT ~0 'd'
5 ASSIGN !0, ~0
9 6 EXT_STMT
7 EXT_FCALL_BEGIN
8 SEND_REF !0
9 DO_FCALL 1 'current'
10 EXT_FCALL_END
11 ASSIGN $3 !1, $2
12 JMPZ $3, ->24
11 13 EXT_STMT
14 ECHO '%3CATTR%3E'
15 ECHO !1
16 ECHO '%3C%2FATTR%3E'
17 ECHO '%0A'
12 18 EXT_STMT
19 EXT_FCALL_BEGIN
20 SEND_REF !0
21 DO_FCALL 1 'next'
22 EXT_FCALL_END
13 23 JMP ->7
37 24 RETURN 1
25* ZEND_HANDLE_EXCEPTION

用这个脚本:

$data = array('a', 'b', 'c', 'd');
while ($item = current($data))
{
echo "<ATTR>$item</ATTR>\n";
next($data);
}

你会得到:

line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
19 0 EXT_STMT
1 INIT_ARRAY ~0 'a'
2 ADD_ARRAY_ELEMENT ~0 'b'
3 ADD_ARRAY_ELEMENT ~0 'c'
4 ADD_ARRAY_ELEMENT ~0 'd'
5 ASSIGN !0, ~0
20 6 EXT_STMT
7 EXT_FCALL_BEGIN
8 SEND_REF !0
9 DO_FCALL 1 'current'
10 EXT_FCALL_END
11 ASSIGN $3 !1, $2
12 JMPZ $3, ->25
22 13 EXT_STMT
14 INIT_STRING ~4
15 ADD_STRING ~4 ~4, '%3CATTR%3E'
16 ADD_VAR ~4 ~4, !1
17 ADD_STRING ~4 ~4, '%3C%2FATTR%3E%0A'
18 ECHO ~4
23 19 EXT_STMT
20 EXT_FCALL_BEGIN
21 SEND_REF !0
22 DO_FCALL 1 'next'
23 EXT_FCALL_END
24 24 JMP ->7
39 25 RETURN 1
26* ZEND_HANDLE_EXCEPTION

(此输出使用 PHP 5.2.6,这是 Ubuntu Jaunty 上的默认设置)

最后,您可能会注意到并没有太大的区别,而且通常只是-优化^^

可能更有趣的是查看 PHP 版本之间的差异:例如,您可能会看到某些操作已在 PHP 5.1 和 5.2 之间进行了优化。

更多信息,你也可以看看Understanding Opcodes

玩得开心!

编辑:添加另一个测试:

使用此代码:

$attr_open = '<ATTR>';
$attr_close = '</ATTR>';
$eol = "\n";

$data = array('a', 'b', 'c', 'd');
while ($item = current($data))
{
echo $attr_open, $item, $attr_close, $eol;
next($data);
}

你得到:

line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
19 0 EXT_STMT
1 ASSIGN !0, '%3CATTR%3E'
20 2 EXT_STMT
3 ASSIGN !1, '%3C%2FATTR%3E'
21 4 EXT_STMT
5 ASSIGN !2, '%0A'
23 6 EXT_STMT
7 INIT_ARRAY ~3 'a'
8 ADD_ARRAY_ELEMENT ~3 'b'
9 ADD_ARRAY_ELEMENT ~3 'c'
10 ADD_ARRAY_ELEMENT ~3 'd'
11 ASSIGN !3, ~3
24 12 EXT_STMT
13 EXT_FCALL_BEGIN
14 SEND_REF !3
15 DO_FCALL 1 'current'
16 EXT_FCALL_END
17 ASSIGN $6 !4, $5
18 JMPZ $6, ->30
26 19 EXT_STMT
20 ECHO !0
21 ECHO !4
22 ECHO !1
23 ECHO !2
27 24 EXT_STMT
25 EXT_FCALL_BEGIN
26 SEND_REF !3
27 DO_FCALL 1 'next'
28 EXT_FCALL_END
28 29 JMP ->13
43 30 RETURN 1
31* ZEND_HANDLE_EXCEPTION

并且,用这个(连接而不是','):

$attr_open = '<ATTR>';
$attr_close = '</ATTR>';
$eol = "\n";

$data = array('a', 'b', 'c', 'd');
while ($item = current($data))
{
echo $attr_open . $item . $attr_close . $eol;
next($data);
}

你得到:

line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
19 0 EXT_STMT
1 ASSIGN !0, '%3CATTR%3E'
20 2 EXT_STMT
3 ASSIGN !1, '%3C%2FATTR%3E'
21 4 EXT_STMT
5 ASSIGN !2, '%0A'
23 6 EXT_STMT
7 INIT_ARRAY ~3 'a'
8 ADD_ARRAY_ELEMENT ~3 'b'
9 ADD_ARRAY_ELEMENT ~3 'c'
10 ADD_ARRAY_ELEMENT ~3 'd'
11 ASSIGN !3, ~3
24 12 EXT_STMT
13 EXT_FCALL_BEGIN
14 SEND_REF !3
15 DO_FCALL 1 'current'
16 EXT_FCALL_END
17 ASSIGN $6 !4, $5
18 JMPZ $6, ->30
26 19 EXT_STMT
20 CONCAT ~7 !0, !4
21 CONCAT ~8 ~7, !1
22 CONCAT ~9 ~8, !2
23 ECHO ~9
27 24 EXT_STMT
25 EXT_FCALL_BEGIN
26 SEND_REF !3
27 DO_FCALL 1 'next'
28 EXT_FCALL_END
28 29 JMP ->13
43 30 RETURN 1
31* ZEND_HANDLE_EXCEPTION

所以,从来没有太大的区别^^

关于php - 如何使 PHP 更快 : Does String Creation Have No Cost?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1156989/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com