关注LAMP|PHP源代码分析|web架构|PHP扩展|Erlang|服务端架构
  • PHP中Exception性能简单测试及结论

    2009-11-18

    关于是否使用exception风格(个人的说法,也就是非正常的返回值都以抛异常的形式返回)来编码,我产生了一些疑问,经过和同事的一些讨论,我决定做些简单的性能测试。

    <?php

    /**

     * Exception 简单的性能测试

     * @author Qingliang.Cn  qing.liang.cn@gmail.com

     * @created 2009-11-18 

     * @lastmodified 2009-11-18

     */

    define(‘T’1000000);

    function no_except($a$b)

    {

        if (mt_rand(110) > 0){

            return $a $b;

        }

    }

    function except($a$b)

    {

        try {

            if (mt_rand(110) > 5){ //  0.5的概率抛出异常

                return $a $b;

            }else{

                throw new Exception(1);

            }

        }catch (Exception $e){

            return $e->getMessage();

        }

    }

    echo "1. with no exception, time is:";

    $begin = microtime(true);

    for ($i=0$i< T; $i++)

    {

        no_except(11);

    }

    echo microtime(true) - $begin;

    echo "\r\n";

    echo "2. with exception, time is:";

    $begin = microtime(true);

    for ($i=0$i< T; $i++)

    {

        except(11);

    }

    echo microtime(true) - $begin;

    echo "\r\n";

    结果:

    100000 (10W)

    1. with no exception, time is:3.2554759979248

    2. with exception, time is:4.2815051078796

    1000000(100W)

    1. with no exception, time is:31.89279794693

    2. with exception, time is:39.047714948654

    上面的测试结果可以看出消耗的时间是相当稳定的,直接的结果是exception比直接return要慢。 

    继续分析

    抛出异常的概率为0.5,也就是说:50w次的异常处理导致了11秒的性能损失。每次exception处理的消耗大概是 20 微秒,这个消耗是相当的小的。 因为一般情况下,web请求的时间都是ms级别的。

    同时这里还有两点需要注意:

    1. 没有使用异常的时候,代码中的逻辑判断分值必然会加多,也是一定的消耗。

    2. 多数的程序exception命中率不会如上面代码中那么高(50%)。

    所以在PHP中应用exception是不需要考虑性能问题的。

    如有不同的观点,欢迎拍砖和讨论。 email: qing.liang.cn at gmail.com

    作者:庆亮 | 分类目录:PHP高级应用 | 标签:
  • PHP中memcache扩展set失败的解决

    2009-07-04

    在代码中遇到了memcache set方法失败的问题,无任何错误提示,PHP的memcache扩展本身也没有debug或者error提示。同样的代码,将本地的环境跟服务器的环境对比了一下(在服务器端一直没有遇到这个问题),发现原来是我所使用的php memcache扩展版本较低导致的。PECL有个bug报告http://pecl.php.net/bugs/bug.php?id=9486 ,也是提到这个问题了,在新的版本中已经解决了(2.1.1)。

    使用php的memcache扩展时,如果给set/get方法传递一个空值(NULL),则会导致memcached服务端主动关闭连接,见如下的代码示范:
     

    $mem new Memcache();

    $mem->connect(’192.168.64.12′’11211′);

    $mem->set(‘aaa’array(‘aaa’)); //成功

    $mem->set($aaaa‘aaaa’); //失败,并导致到memcached服务器的连接丢失,所以之后的方法都失败了(返回false)

    $mem->set(‘bbb’array(‘bbb’));//失败

    $mem->get(‘aaa’);//失败

    没有测试memcached扩展是否有过这样的bug。
    顺便提一下在PHP中memcached和memcache是两个不同的扩展,区别是memcached基于libmemcached库封装的API接口。见PHP手册
    This extension uses libmemcached library to provide API for communicating with memcached servers. It also provides a session handler (memcached).

    而通常所说的memcached就是指memcached服务器端。

    另外如果key过长(250以上),value过大(1M以上)或者过期时间过长(大于2592000)都会导致set失败。

    作者:庆亮 | 分类目录:PHP高级应用 | 标签: