php 代码测试,代码越在前面越耗时

2014-06-16 09:33:09 +08:00
 yakczh
function test(){
$i=100;
$arr=array();
do { array_push($arr,$i); }while ($i--);
}


$func='test';



$cnt=10000;
$start=microtime(true);
do {
call_user_func($func);
}while ($cnt--);
$end=microtime(true);
echo "\ncall_user_func exec time " ,$end-$start;




$cnt=10000;
$start=microtime(true);
do {
$func();
} while ($cnt--);
$end=microtime(true);
echo "\ncall_by_name exec time " ,$end-$start;


结果是
call_user_func exec time 1.7575268745422
call_by_name exec time 1.3825221061707

如果两段代码换个位置 结果是

call_by_name exec time 1.7725269794464
call_user_func exec time 1.3875210285187
从结果看来,性能跟代码实现没关系,只跟位置有关系
3999 次点击
所在节点    PHP
19 条回复
yangqi
2014-06-16 09:40:58 +08:00
你这个代码运行个10次100次,然后去个平均数再看看能不能得到相同结果在下结论
yakczh
2014-06-16 09:54:35 +08:00
10次
call_by_name exec time 0.002500057220459
call_user_func exec time 0.002500057220459
100次
call_by_name exec time 0.022500991821289
call_user_func exec time 0.022500038146973
yangqi
2014-06-16 09:59:56 +08:00
@yakczh 所以说你开始的结论不成立
rannnn
2014-06-16 10:00:52 +08:00
运行一次1秒多 10次0.002?
9
2014-06-16 10:11:42 +08:00
call_user_func($func) 比 $func(); 多绕了一步, 耗时多点不是很正常吗.
skydiver
2014-06-16 10:23:42 +08:00
猜测:第一次执行一个函数要加载,第二次不用了。。
yakczh
2014-06-16 10:30:18 +08:00
@9 运行10次 耗时相同,推翻了我的结论
运行100次 call_user_func 耗时更少, 你从哪里看出耗时多点了?
yangqi
2014-06-16 10:33:36 +08:00
@yakczh 我是让你整段代码运行10次, 100次, 不是循环减少到10次和100次...
9
2014-06-16 10:59:13 +08:00
@yakczh 我都不知道你怎么测的, 我这里是这样.

9
2014-06-16 11:03:05 +08:00
是 10w 次
yakczh
2014-06-16 11:20:22 +08:00
@9 代码段换了位置,应该输出不一样
yakczh
2014-06-16 11:28:16 +08:00
@9 给你一步一步举个例子说明 第一步 函数实现不变,先运行$func() 再运行call_user_func($func);

...
$func='test';

define('REPEAT',10000*10);



$cnt=REPEAT;
$start=microtime(true);
do {
$func();
} while ($cnt--);
$end=microtime(true);
echo "\ncall_by_name exec time " ,$end-$start;



$cnt=REPEAT;
$start=microtime(true);
do {
call_user_func($func);
}while ($cnt--);
$end=microtime(true);
echo "\ncall_user_func exec time " ,$end-$start;

输出结果 应该是 call_by_name exec time 11.320173978806
call_user_func exec time 10.576663970947

第二步, 函数实现不变,先运行call_user_func($func); 再运行 $func()
...
$func='test';

define('REPEAT',10000*10);


$cnt=REPEAT;
$start=microtime(true);
do {
call_user_func($func);
}while ($cnt--);
$end=microtime(true);
echo "\ncall_user_func exec time " ,$end-$start;


$cnt=REPEAT;
$start=microtime(true);
do {
$func();
} while ($cnt--);
$end=microtime(true);
echo "\ncall_by_name exec time " ,$end-$start;
输出结果应该是
call_user_func exec time 11.387675046921
call_by_name exec time 10.002654075623

然后思考 函数实现与输出结果之间的相关性
0xef
2014-06-16 11:36:57 +08:00
越在前面越耗时是可能的

因为可能存在缓存。内存的缓存(例如预先malloc),文件信息的缓存(当然跟这里的话题)。首次运行某些函数可能会建立缓存所以会慢一些,而后来的运行因为有缓存的存在所有会快一些

http://cogug.com/ur9893
9
2014-06-16 11:41:49 +08:00
不就是2个代码段互换过来跑吗. 我这边是这样.

yakczh
2014-06-16 11:50:34 +08:00
从输出结果就看出来不对,或者你修改了原始程序
9
2014-06-16 11:53:23 +08:00
哪里不对, 前后发的两张图的时间都差不多. 我俩机器不一样, 我的时间跟你的时间不同很正常啊
yakczh
2014-06-16 12:15:38 +08:00
yakczh
2014-06-16 12:36:40 +08:00
rannnn
2014-06-16 13:38:15 +08:00


理论上应该是call_user_func慢的
然后找到call_user_func的定义,里面有个zend_fcall_info_cache保存了一些scope的信息貌似
所以我猜第一次call的时候会缓存。所以摆在前面的比较慢

不懂 core 瞎猜的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/117711

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX