2015-01-06 126 views
1

每隔一段时间我都会看到关于SO的问题,其答案/解决方案包括使用get_defined_vars()或使用该方法的互联网上的博客文章。在大多数情况下,它用于调试目的,但在某些情况下,似乎作者有意在生产代码中使用它。get_defined_vars()`对性能的影响是什么?

虽然我很少使用这个函数,因为它让我感觉内在,我想知道使用这个函数的实际性能影响是在PHP应用程序中。

它的一个example的使用可能会看到一个变量是否明确设置为NULL

//$implicit_null = 1234; 
$explicit_null = NULL; 

var_dump(is_null($implicit_null)); // TRUE, also throws undefined index error 
var_dump((
    array_key_exists('implicit_null',get_defined_vars()) && 
    is_null($implicit_null) 
)); // FALSE 

还有其他的用例在互联网上流传,但很少勾画的性能或内存的影响也许。

+0

@PaulCrovella - 我有一个方法,并有,这就是为什么我按下“回答你自己的问题”按钮。我专门提出了这个问题,所以我可以回答。也就是说,我也会对其他人的发现或更正感兴趣。 – Mike

+0

这是公平的,我有一个衡量代码块性能的相当标准的方法,但是在我自己去测试这些测试之前,我会经常看Google,看看它是否值得。第一。也就是说,还有一些关于这个问题的SO问题/答案,所以它有助于得到一个关于它的性能的坚实的SO答案。 – Mike

回答

2

事实证明,内存的影响可能会有所不同,但在最坏的情况下,它可以接近double your memory usage

function report_memory($string = '') { 
    $mem = (memory_get_usage()/1000); 
    echo "$string: {$mem}kb\n"; 
    return $mem; 
} 

// ~117.164kb 
$start = report_memory('Start of stript'); 

for($i = 10000; $i > 0; $i--) { 
    $var = "filler_$i"; 
    $$var = 'banana'; 
} 

// ~1022.752kb after fill 
$fill_size = ($after_fill = report_memory('After banana')) - $start; 
// ~905.588kb fill size 
echo "Fill Size: {$fill_size}kb\n\n"; 

$tmp_vars = get_defined_vars(); 

// ~1649.12kb after function call 
$grew = report_memory('After get_defined_vars()') - $after_fill; 
// ~626.368kb growth due to call 
echo "Growth from get_defined_vars(): {$grew}kb\n\n"; 

再次,这是最坏的情况。当用array_fill()填充数组时,我确实看到some odd behavior。正如你在这里看到的,与创建变量本身相比,调用get_defined_vars()的增长非常小。起初,我认为这是由于array作为参考返回,但这是clearly not the case。但是,应该注意的是,对象将始终为returned as references。所有这一切都说,所有的全局变量都不可能是数组上的数组,而且所有这些字符串,二进制数据和数字将会相当快地累加起来。

最后,这是一个单一的功能,可以增加近一倍的内存占用,并造成一significant wall-time

for($i = 10000; $i > 0; $i--) { 
    $var = "filler_$i"; 
    $$var = 'banana'; 
} 

$start = microtime(true); 

for($i = 250; $i > 0; $i--) { 
    $all = get_defined_vars(); 
} 

$stop = microtime(TRUE); 
echo round(((($stop - $start))/250)*1000000, 2); // ~1967.45 microseconds 

总结论

使用进行调试,我不会甚至没有习惯在夜晚将代码留在代码中。谨慎使用。

相关问题