轮廓
每当对几种可能性的相对表现有疑问时,不要依赖其他人的建议(这可能是纯粹的猜测):profile。
DebugKit带有一个Benchmark shell,它是一种生成基准信息的便捷方式(seige和ab是两个更准确/可靠的替代方案):
$ cd my/app
$ Console/cake DebugKit.benchmark
Allows you to obtain some rough benchmarking statistics about a fully
qualified URL.
Usage:
cake debug_kit.benchmark [-h] [-v] [-q] [--n 10] [--t 100] <url>
Options:
--help, -h Display this help.
--verbose, -v Enable verbose output.
--quiet, -q Enable quiet output.
--n Number of iterations to perform. (default:
10)
--t Maximum total time for all iterations, in seconds.If a
single iteration takes more than the tiemout, only one request will be
made (default: 100)
Arguments:
url The URL to request.
Example Use: `cake benchmark --n 10 --t 100 http://localhost/testsite`.
Note: this benchmark does not include browser render times.
使用这样的工具将解决大多数关于性能的疑问 - 只需设置几个控制器操作并注意每个操作的相对性能。
为什么要限制自己有两种可能性?
让我们假设问题不在于使用 requestAction 是否比总是填充可能不会使用的变量更好(提示),而是:在所有/大多数页面上显示 <something> 的最佳方式是什么?
这里有两条简单的规则,可能可以解决大多数问题:
- 使用缓存
- 不要索要您不会使用的数据/仅在您将要使用时才索取数据
在某些方面,提出的两个选项requestAction
中更合适 - 但还有其他选项可以达到与给出的示例相同的结果。
元素缓存
而不是总是(一种或另一种方式)获取数据 - 获取一次并且在数据陈旧之前不要再次获取它。例如,在布局中使用元素缓存,以便元素中的任何内容都不会在每个请求上执行:
echo $this->element(
'footer',
array(),
"cache" => array('config' => 'element_config', 'key' => 'footer')
);
元素的内容footer
应该是自给自足的,例如:
<?php
$User = ClassRegistry::init('User');
// $betterExample = $User->expensiveCall(); // more relevant where the call is slow
$totalUsers = $User->find('count');
?>
<div class="footer">Currently, we have <?php echo $totalUsers;?> registered users.</div>
这样,只有在没有缓存结果时才请求元素的数据。通过调整相关的缓存配置(适当的缓存配置取决于要求 - 需要或多或少是实时的?使用例如 30 秒的缓存配置;是否过时无关紧要?使用 1 天),计数器的频率可以修改更新。
或者,可以使用无限缓存时间,而是仅在值更改时才清除缓存:
class User extends AppModel {
public function updateCounterCache($keys = array(), $created = false) {
Cache::delete('footer', 'element_config');
return parent::updateCounterCache($keys, $created);
}
}
其他技术?
还有其他类似的技术可以使用(包括将元素与 结合使用requestAction
) - 但原则始终相同:不要急于执行可能不需要的逻辑(获取数据),有效地使用缓存。