PHP5 - PHP5中的RTTI(获取类名称等)的成本是多少?

时间:2009-11-08 19:34:19

标签: php performance

我注意到一些PHP框架,比如Kohana和CodeIgniter,会查看类的类名来执行自动加载。传统上,RTTI对C ++来说很昂贵;与以下相比,PHP5的价格是多少:

  1. 直接留言
  2. 查找关联数组中的键
  3. 通过变量进行消息调用($ class ='foobar'; $ method ='foo'; $ class-> $ method())

2 个答案:

答案 0 :(得分:3)

一般情况下,如果您使用的是PHP,性能不应该是您最大的担忧,首先要编写好看的代码(即可读和可维护,自我记录等),然后根据需要进行配置和优化。如果你开始担心速度,那么PHP可能不是你想要的。

但是要回答你的问题...... get_class有相当不错的性能,我认为它在zend引擎中得到了很好的优化。尝试调用不存在的函数并处理错误太多更昂贵。 (调用一个不存在的函数是一个致命的错误,除非你在基础对象中写了一堆粘合代码,否则你不会捕获它)

这里有一些基准测试,以显示确定运行方法的能力的一些不同方法。

benchmark.php:

<?php

class MyClass {
    public function Hello() {
        return 'Hello, World!';
    }
}

function test_get_class( $instance ) {
    $t = get_class( $instance );
}

function test_is_callable( $instance ) {
    $t = is_callable( $instance, 'Hello' );
}

function test_method_exists( $instance ) {
    $t = method_exists( $instance, 'Hello' );
}

function test_just_call( $instance ) {
    $result = $instance->Hello();
}

function benchmark($iterations, $function, $args=null) {
    $start = microtime(true);
    for( $i = 0; $i < $iterations; $i ++ ) {
        call_user_func_Array( $function, $args );
    }
    return microtime(true)-$start;
}

$instance = new MyClass();

printf( "get_class:     %s\n", number_format(benchmark( 100000, 'test_get_class', array( $instance ) ), 5) );
printf( "is_callable:   %s\n", number_format(benchmark( 100000, 'test_is_callable', array( $instance ) ), 5) );
printf( "method_exists: %s\n", number_format(benchmark( 100000, 'test_method_exists', array( $instance ) ), 5) );
printf( "just_call:     %s\n", number_format(benchmark( 100000, 'test_just_call', array( $instance ) ), 5) );

?>

结果:

get_class:     0.78946
is_callable:   0.87505
method_exists: 0.83352
just_call:     0.85176

答案 1 :(得分:0)

RTTI在C ++中很昂贵的原因是因为你需要额外的查找步骤(例如vtable)。以函数调用为例。结果比将程序计数器寄存器移动到承载功能代码的存储器地址慢得多。

我还没有看到PHP引擎的实现,但我怀疑作为一种解释语言,这种“开销”要么是必须的(鉴于它不编译程序,它需要弄清楚在哪里调用函数无论如何),或者与口译语言的所有其他开销相比是最小的。

尽管如此,调查的最佳方法是进行简单的实验并对结果进行分析。你可以有两个程序,一个使用RTTI进行函数调用,另一个使用直接调用,并比较两者的结果。