【问题标题】:Does PHP's range('A', 'Z') return a static array?PHP 的 range('A', 'Z') 是否返回静态数组?
【发布时间】:2012-02-18 01:18:58
【问题描述】:

我忽略了一些我为在产品页面上生成 A-Z 导航而编写的代码,其完成方法是 for 循环;使用ascii octals 65-91 和PHP 的chr() 函数。我想知道是否有更简单和/或更有效的方法来做到这一点,我发现 PHP 的 range() 函数支持字母范围。

在我编写了测试代码来比较不同的方法后,我想到了几个问题:

  1. PHP 是否存储字母表的静态数组?
  2. 我怎样才能更深入地查看 PHP 层下面的配置文件 发生了什么事?

除了环境配置之外,我还有一个 PHP 脚本的缓存,如有必要,可以附加它。对于那些可能想知道执行它的机器规格的人,这里有一些链接:

root@workbox:~$ lshw http://pastebin.com/cZZRjJcR

root@workbox:~$ 系统信息 http://pastebin.com/ihQkkPAJ

<?php
/*
 * determine which method out of 3 for returning
 * an array of uppercase alphabetic characters 
 * has the highest performance
 * 
 * +++++++++++++++++++++++++++++++++++++++++++++
 * 
 * 1) Array $alpha = for($x = 65; $x < 91; $x++) { $upperChr[] = chr($x); }
 * 2) Array $alpha = range(chr(65), chr(90);
 * 3) Array $alpha = range('A', 'Z');
 * 
 * +++++++++++++++++++++++++++++++++++++++++++++
 * 
 * test runs with iterations:
 * 
 * 10,000:
 * - 1) upperChrElapsed: 0.453785s
 * - 2) upperRangeChrElapsed: 0.069262s
 * - 3) upperRangeAZElapsed: 0.046110s
 * 
 * 100,000:
 * - 1) upperChrElapsed: 0.729015s
 * - 2) upperRangeChrElapsed: 0.078652s
 * - 3) upperRangeAZElapsed: 0.052071s
 * 
 * 1,000,000:
 * - 1) upperChrElapsed: 50.942950s
 * - 2) upperRangeChrElapsed: 10.091785s
 * - 3) upperRangeAZElapsed: 8.073058s
 */

ini_set('max_execution_time', 0);
ini_set('memory_limit', 0);

define('ITERATIONS', 1000000); // 1m loops x3

$upperChrStart = microtime(true);
for($i = 0; $i <= ITERATIONS; $i++) {
    $upperChr = array();
    for($x = 65; $x < 91; $x++) {
            $upperChr[] = chr($x);
    }
}
$upperChrElapsed = microtime(true) - $upperChrStart;

// +++++++++++++++++++++++++++++++++++++++++++++

$upperRangeChrStart = microtime(true);
for($i = 0; $i <= ITERATIONS; $i++) {
    $upperRangeChr = range(chr(65), chr(90));   
}
$upperRangeChrElapsed = microtime(true) - $upperRangeChrStart;

// +++++++++++++++++++++++++++++++++++++++++++++

$upperRangeAZStart = microtime(true);
for($i = 0; $i <= ITERATIONS; $i++) {
    $upperRangeAZ = range('A', 'Z');    
}
$upperRangeAZElapsed = microtime(true) - $upperRangeAZStart;

printf("upperChrElapsed: %f\n", $upperChrElapsed);
printf("upperRangeChrElapsed: %f\n", $upperRangeChrElapsed);
printf("upperRangeAZElapsed: %f\n", $upperRangeAZElapsed);

?>

【问题讨论】:

  • 我不了解你,但我从来没有让我担心过额外的 2 微秒。这是我对 PHP 的主要问题:不是语言本身,而是坚持做无用废话基准测试的稻草人。一些不应该在循环中的东西的一百万次迭代需要额外的 2 秒!哦,gn0!噗
  • @cHao 为自己说话。在我们的应用程序主循环中多花 2 微秒,我们必须为每个数据中心额外购买 3,000 美元的硬件。如果在一个内部循环中是 2 微秒,则成本更高。
  • @Crashworks:如果那一点速度差异要花那么多钱,那么坦率地说,你不应该使用 PHP。您可以改用 C++(甚至 (C#)),这样可以节省数百万美元。当然,这里真正的优化(将 create-the-same-array-we-just-used 的东西移出循环)是免费的。关键是,最快的两个之间的速度差异可以忽略不计,与更快地创建数组相比,改进算法可以更好地解决速度问题。

标签: php performance profiling


【解决方案1】:

PHP 是否会浪费内存来保存字母数组?我会怀疑的。 range() 也适用于各种值。

如果在这种情况下性能是一个问题,您可能希望在循环之外声明该数组,以便可以重复使用它。然而,巨大的收益很少来自微优化。在大型应用程序上使用分析以获得显着收益。

对于较低级别的分析,您可以简单地在 PHP CLI 上使用 valgrind。我还看到它用于 apache 进程。

相关:How to profile my C++ application on linux

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多