Php 为什么这表现更好?
因此,我试图使用Php 为什么这表现更好?,php,performance,reflection,aop,debug-backtrace,Php,Performance,Reflection,Aop,Debug Backtrace,因此,我试图使用debug\u backtrace和PHP反射在我的体系结构中实现一个面向方面的设计。设计是可行的,但我决定看看它对性能的影响有多严重,所以我编写了下面的评测测试。有趣的是,当可取的和不可取的方法不起作用时,其影响大约是使用可取方法与使用不可取方法的5倍,但是当我增加每个方法的复杂性时(这里通过将迭代次数增加到30或更多),建议的方法开始执行得更好,并随着复杂性的增加而继续增加 基类: abstract class Advisable { private static
debug\u backtrace
和PHP反射在我的体系结构中实现一个面向方面的设计。设计是可行的,但我决定看看它对性能的影响有多严重,所以我编写了下面的评测测试。有趣的是,当可取的
和不可取的
方法不起作用时,其影响大约是使用可取方法与使用不可取方法的5倍,但是当我增加每个方法的复杂性时(这里通过将迭代次数增加到30或更多),建议的方法开始执行得更好,并随着复杂性的增加而继续增加
基类:
abstract class Advisable {
private static $reflections = array();
protected static $executions = 25;
protected static function advise()
{
$backtrace = debug_backtrace();
$method_trace = $backtrace[1];
$object = $method_trace['object'];
$function = $method_trace['function'];
$args = $method_trace['args'];
$class = get_called_class();
// We'll introduce this later
$before = array();
$around = array();
$after = array();
$method_info = array(
'args' => $args,
'object' => $object,
'class' => $class,
'method' => $function,
'around_queue' => $around
);
array_unshift($args, $method_info);
foreach ($before as $advice)
{
call_user_func_array($advice, $args);
}
$result = self::get_advice($method_info);
foreach ($after as $advice)
{
call_user_func_array($advice, $args);
}
return $result;
}
public static function get_advice($calling_info)
{
if ($calling_info['around_queue'])
{
$around = array_shift($calling_info['around_queue']);
if ($around)
{
// a method exists in the queue
return call_user_func_array($around, array_merge(array($calling_info), $calling_info['args']));
}
}
$object = $calling_info['object'];
$method = $calling_info['method'];
$class = $calling_info['class'];
if ($object)
{
return null; // THIS IS THE OFFENDING LINE
// this is a class method
if (isset(self::$reflections[$class][$method]))
{
$parent = self::$reflections[$class][$method];
}
else
{
$parent = new ReflectionMethod('_'.$class, $method);
if (!isset(self::$reflections[$class]))
{
self::$reflections[$class] = array();
}
self::$reflections[$class][$method] = $parent;
}
return $parent->invokeArgs($object, $calling_info['args']);
}
// this is a static method
return call_user_func_array(get_parent_class($class).'::'.$method, $calling_info['args']);
}
}
实现的类:
abstract class _A extends Advisable
{
public function Advisable()
{
$doing_stuff = '';
for ($i = 0; $i < self::$executions; $i++)
{
$doing_stuff .= '.';
}
return $doing_stuff;
}
public function NonAdvisable()
{
$doing_stuff = '';
for ($i = 0; $i < self::$executions; $i++)
{
$doing_stuff .= '.';
}
return $doing_stuff;
}
}
class A extends _A
{
public function Advisable()
{
return self::advise();
}
}
有什么想法吗?当你调用A的方法时,你跳过了所有的迭代。。。您只需调用一次继承的advice()方法就可以覆盖它。因此,当您添加迭代时,您只是将它们添加到非建议()调用中。当您调用A的建议方法时,您跳过了所有的迭代。。。您只需调用一次继承的advice()方法就可以覆盖它。因此,当您添加迭代时,您只是将它们添加到NonAdvisable()调用中。应该适用于PHP和Java,我想——“调用的实际方法是在运行时确定的”=>shadowed
Advisible
方法的开销更大
但是它应该是O(1)而不是不可取的
的O(n)应该应用于PHP和Java,我想-“调用的实际方法是在运行时确定的”=>隐藏的Advisible
方法的开销更大
但是它将是O(1)而不是
不可取的
的O(n)很抱歉,我刚刚发现行返回null在调用父方法之前,在get_advice
方法中执行code>。我不想回答我自己的问题,但不值得别人去搜索。很抱歉,我刚刚发现行返回null在调用父方法之前,在get_advice
方法中执行code>。我不想回答我自己的问题,但不值得其他人搜索。使用microtime分析此代码是不合适的。使用像XDebug这样的探查器,它可以为各个方法收集数据。然后你就会知道是什么导致了什么。没关系,我已经弄明白了。我在get_advice()方法中留下了一些调试代码,该方法立即返回null。复杂度为25的开销大约为2.5:1,我认为还不错,并且从那以后它会减少。不过,我会详细研究XDebbug。使用microtime分析此代码是不合适的。使用像XDebug这样的探查器,它可以为各个方法收集数据。然后你就会知道是什么导致了什么。没关系,我已经弄明白了。我在get_advice()方法中留下了一些调试代码,该方法立即返回null。复杂度为25的开销大约为2.5:1,我认为还不错,并且从那以后它会减少。不过,我会彻底调查XDebbug。
$a = new A();
$start_time = microtime(true);
$executions = 1000000;
for ($i = 0; $i < $executions; $i++)
{
$a->Advisable();
}
$advisable_execution_time = microtime(true) - $start_time;
$start_time = microtime(true);
for ($i = 0; $i < $executions; $i++)
{
$a->NonAdvisable();
}
$non_advisable_execution_time = microtime(true) - $start_time;
echo 'Ratio: '.$advisable_execution_time/$non_advisable_execution_time.'<br />';
echo 'Advisable: '.$advisable_execution_time.'<br />';
echo 'Non-Advisable: '.$non_advisable_execution_time.'<br />';
echo 'Overhead: '.($advisable_execution_time - $non_advisable_execution_time);
Ratio: 0.289029437803
Advisable: 7.08797502518
Non-Advisable: 24.5233671665
Overhead: -17.4353921413