通过PHP静态变量进行缓存
当一段代码里在重复使用一个方法调用时,你也许会问如果把值本地缓存起来难道不会更有效率,这样完全避免函数调用而提高处理速度。让我来看看我们如何可能来使用缓存通过PHP的静态变量。
函数调用是非常资源密集对的:PHP需要设置一个新的调用环境,导入(supper)全局变量,创建一些新的变量(参数),然后再完成的时候清理它们所有的东西。而且这对PHP的内建函数也是一样的。避免它可以帮助每个人节约一些工作。
一些函数会总是返回相同的结果,如果传给它相同的参数的话:这些就是那些可以缓存的。这个也是for循环如果喜剧性地加快速度的:
<?php for($i = 0 ; $i < count($array) ; $i++) { /* Do something */ } ?>
这里,count($array)将会总是返回相同的值。完全没有必要每一次都去计算它,所以将它保存到本地变量将会加快很多循环的速度。
<?php $count = count($array) ; for($i = 0 ; $i < $nb ; $i++) { /* Do something */ } ?>
同样这个也适用于任何类似情况代码,甚至在循环的外面。
<?php $store = new Store(); $store->in(dirname(__DIR__). DS. 'Catalog') ->in(dirname(__DIR__). DS. 'Source') ->in(dirname(__DIR__). DS. 'PrivateList') ->name('#\.php$#'); ?>
这里,’dirname( _DIR _) . DS’ 调用可以通过保存这个片段的结果在一个本地变量来避免。
<?php $store = new Store(); $path = dirname(__DIR__). DS ; $store->in($path. 'Catalog') ->in($path. DS. 'Source') ->in($path. 'PrivateList') ->name('#\.php$#'); ?>
很容易能够通过benchmark基准来显示上面的改变实际上会使上面的代码几乎快2倍。而且,使用dirname()越多,得到的优化更多。
使用静态变量
现在,让我们来考虑一个非常好的PHP功能:静态变量。这样一个关键字,当对一个在函数内用到的变量使用时,会使该变量在反复函数调用之间继续存在(请不要把这个和静态的类成员混淆)。你可以把它比成像专门为一个函数保留的全局变量。这是上面的代码的一个更新版本:
<?php $store = new Store(); static $path ; if (!isset($path)) { $path = dirname(__DIR__). DS ; } $store->in($path. 'Catalog') ->in($path. 'Source') ->in($path. 'PrivateList') ->name('#\.php$#');
一旦初始化,$path变量对每一次调用时都有效。这个给这个代码带来另外2被的速度提升!而且,就像前面的,更多dirname(…)更好。
能更快吗?
剩下的下面两个选择来进一步提升代码是用值hardcode或使它成为一个常量。Hardcode永远都是一个坏主意,而且在像例子中的代码里很难管理,因为 _DIR _可能基于不同的部署安装而不同。使用一个常量通常是一个提升速度方面的好主意,但在我们的例子中它有可能也遇到和hardcode一样问题。我们将仅仅考虑这两个不同的方案是作速度提升的其他选择。记得,代码是这样的:
<?php $store = new Store(); $store->in(PATH. 'Catalog') ->in(PATH. DS. 'Source') ->in(PATH. 'PrivateList') ->name('#\.php$#');
<?php $store = new Store(); $store->in("/path/to/files". 'Catalog') ->in("/path/to/files". DS. 'Source') ->in("/path/to/files". 'PrivateList') ->name('#\.php$#'); ?>
下面是跑上面的代码100,000次的benchmarks的结果:
Calling function overtime | 818.37 ms |
Saving result in variable | 364.93 ms |
Saving result in static variable | 175.72 ms |
Result in constant | 161.19 ms |
Hardcoded literal | 154.23 ms |
现在,我们看到函数调用的冲击性了。避免重复的函数调用能够得到非常戏剧性的速度提升。Hardcode的字面值确实是最快的,但是获得的提升是很少的。另一方面,静态变量提供一个十分灵活的本地缓存的解决方案而且获得客观的速度提升。
为谁的速度提升?
很显然,代价昂贵的或慢得函数是我们的提升对象。重复调用的函数,像(模板)层的helper(帮助)或甚至是PHP的源生函数都可以考虑使用本文的技巧。
使用静态变量容许本地优化,不依赖方法自身以外的很多代码。没有启动成本,和没有和其他全局变量冲突的可能。它对于函数以外的代码完全是不可见的,就像它应该做的那样。
另一方面,当缓存的值太多变数,或者函数并不是调用得很频繁,处理缓存将会是一个太多的负担。而且,用这里的技巧来提速一个框架显得完全无望。
English: http://178.62.231.40/cache-with-php-static-variables/