V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yakczh
V2EX  ›  PHP

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

  •  
  •   yakczh · 2014-06-16 09:33:09 +08:00 · 3986 次点击
    这是一个创建于 3814 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
    从结果看来,性能跟代码实现没关系,只跟位置有关系
    19 条回复    2014-06-16 13:38:15 +08:00
    yangqi
        1
    yangqi  
       2014-06-16 09:40:58 +08:00
    你这个代码运行个10次100次,然后去个平均数再看看能不能得到相同结果在下结论
    yakczh
        2
    yakczh  
    OP
       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
        3
    yangqi  
       2014-06-16 09:59:56 +08:00
    @yakczh 所以说你开始的结论不成立
    rannnn
        4
    rannnn  
       2014-06-16 10:00:52 +08:00
    运行一次1秒多 10次0.002?
    9
        5
    9  
       2014-06-16 10:11:42 +08:00
    call_user_func($func) 比 $func(); 多绕了一步, 耗时多点不是很正常吗.
    skydiver
        6
    skydiver  
       2014-06-16 10:23:42 +08:00
    猜测:第一次执行一个函数要加载,第二次不用了。。
    yakczh
        7
    yakczh  
    OP
       2014-06-16 10:30:18 +08:00
    @9 运行10次 耗时相同,推翻了我的结论
    运行100次 call_user_func 耗时更少, 你从哪里看出耗时多点了?
    yangqi
        8
    yangqi  
       2014-06-16 10:33:36 +08:00
    @yakczh 我是让你整段代码运行10次, 100次, 不是循环减少到10次和100次...
    9
        9
    9  
       2014-06-16 10:59:13 +08:00
    @yakczh 我都不知道你怎么测的, 我这里是这样.

    9
        10
    9  
       2014-06-16 11:03:05 +08:00
    是 10w 次
    yakczh
        11
    yakczh  
    OP
       2014-06-16 11:20:22 +08:00
    @9 代码段换了位置,应该输出不一样
    yakczh
        12
    yakczh  
    OP
       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
        13
    0xef  
       2014-06-16 11:36:57 +08:00
    越在前面越耗时是可能的

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

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

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


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

    不懂 core 瞎猜的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2968 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:32 · PVG 21:32 · LAX 05:32 · JFK 08:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.