小智 20
PHP已经对它进行了优化 - 使用copy-on-write分配变量,并通过引用传递对象.在PHP 4中它没有,但无论如何都没有人应该使用PHP 4来获取新代码.
许多语言中最重要的速度优化技术之一是实例重用.在这种情况下,速度增加来自至少2个因素:
1.实例化程度越低意味着建筑时间越少.
2.应用程序使用的内存量越少,可能存在的CPU缓存丢失越少.
对于速度是第一优先级的应用程序,CPU和RAM之间存在真正严重的瓶颈.瓶颈的原因之一是RAM的延迟.
PHP,Ruby,Python等与缓存未命中有关,即使它们至少存储了RAM中解释程序的一些(可能是全部)运行时数据.
字符串实例化是经常以相对"大量"完成的操作之一,并且它可能对速度产生显着影响.
这是测量实验的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
Run Code Online (Sandbox Code Playgroud)
这是./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");
?>
Run Code Online (Sandbox Code Playgroud)
我从这个实验和我使用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);
?>
Run Code Online (Sandbox Code Playgroud)
例如,如果一个人组装包含大量文本的HTML页面,那么人们可能想要考虑顺序,生成的HTML的不同部分如何连接在一起.
可以使用BSD许可的PHP实现和分水岭串联连接算法的Ruby实现.同样的算法可以(已经由我)推广以加速任意精度整数的乘法.