【问题标题】:PHP Microbenchmarking (variables vs. conditional statements)PHP 微基准测试(变量与条件语句)
【发布时间】:2013-10-20 01:42:22
【问题描述】:

这个问题可能是“有点过分”。但或多或少是微基准代码,但它是为了提高我对 PHP 后端的标准和一般知识。

所以!我来了,我的问题!与在 PHP 中调用额外的 else 条件相比,调用两次变量需要更少的内存(和 CPU 负载)吗?哪个需要更多资源?为什么?

以下示例:
A,显示调用一个变量两次,B,显示调用一个附加的 else 条件。 当然,两者都有相同的最终结果

对任何答案(响应)的任何额外引用也将被高度使用!如果可能的话。

示例 A:

$a = 1;
if (isset($array['a']))
{
    $a = $array['a'];
}

$b = NULL;
if (isset($array['b']))
{
    $b = $array['b'];
}



示例 B:

if (isset($array['a']))
{
    $a = $array['a'];
}
else
{
    $a = 1;
}

if (isset($array['b']))
{
    $b = $array['b'];
}
else
{
    $b = NULL;
}

【问题讨论】:

  • 这个问题毫无疑问是有答案的,但它没有任何意义。速度差异是如此之小,以至于您无法在现代硬件上进行测量。

标签: php variables conditional-statements microbenchmark


【解决方案1】:

我感觉这两个生成的 PHP 操作码对于大多数当前版本的 php 来说是相同或等效的。自己玩一下看看:http://blog.ircmaxell.com/2012/07/the-anatomy-of-equals-opcode-analysis.html

为了好玩,这里是通过 php 5.3x 生成的操作码,例如 A:

 2     0  >   ASSIGN                                                   !0, 1
 3     1      ZEND_ISSET_ISEMPTY_DIM_OBJ                    1  ~1      !1, 'a'
 4     2    > JMPZ                                                     ~1, ->6
 5     3  >   FETCH_DIM_R                                      $2      !1, 'a'
       4      ASSIGN                                                   !0, $2
 6     5    > JMP                                                      ->6
 8     6  >   ASSIGN                                                   !2, null
 9     7      ZEND_ISSET_ISEMPTY_DIM_OBJ                    1  ~5      !1, 'b'
10     8    > JMPZ                                                     ~5, ->12
11     9  >   FETCH_DIM_R                                      $6      !1, 'b'
      10      ASSIGN                                                   !2, $6
12    11    > JMP                                                      ->12
13    12  > > RETURN                                                   1

这是示例 B:

 2     0  >   ZEND_ISSET_ISEMPTY_DIM_OBJ                    1  ~0      !0, 'a'
 3     1    > JMPZ                                                     ~0, ->5
 4     2  >   FETCH_DIM_R                                      $1      !0, 'a'
       3      ASSIGN                                                   !1, $1
 5     4    > JMP                                                      ->6
 8     5  >   ASSIGN                                                   !1, 1
11     6  >   ZEND_ISSET_ISEMPTY_DIM_OBJ                    1  ~4      !0, 'b'
12     7    > JMPZ                                                     ~4, ->11
13     8  >   FETCH_DIM_R                                      $5      !0, 'b'
       9      ASSIGN                                                   !2, $5
14    10    > JMP                                                      ->12
17    11  >   ASSIGN                                                   !2, null
19    12  > > RETURN                                                   1

您处理的代码行数、赋值和跳转数量相同。您只是跳过它略有不同,但乍一看似乎唯一的区别是执行顺序,而不是实际执行的命令。

【讨论】:

    【解决方案2】:

    我创建了一个迷你基准测试,看看哪个更快。 下面精确地评估这两个函数 100 次。 在这两个函数内部,它们会准确地评估您的示例 100,000 次。 在我家的 Ubuntu Web 服务器上,输出与此类似。

    6.0754749774933 = 给变量一个默认值。

    4.8433840274811 = 改用 else 语句。

    第二个示例(else 语句)快了两秒,但是该示例执行了 10,000,000(1000 万)次。在一个真实的例子中,代码的可读性和您的团队喜欢什么比节省几毫秒更重要。

    回答您的问题,使用任何一种方法几乎是 0。

    如果你想要我的意见,我更喜欢第二个例子。

    这是我使用的基准测试代码。 http://phpfiddle.org/api/raw/8nm-d72

    【讨论】:

    • 很有趣!不是 4.84
    【解决方案3】:

    我没有计时,但是else中没有评价。如果你有一个 elseif 可能会有一些无限小的差异。这个例子可能归结为可读性和/或编码偏好。

    【讨论】:

      【解决方案4】:

      忽略最小的性能差异,最好先定义一个变量。

      PHP 还不是类型安全的(但),想象一下您的 示例 B 会导致 2 种不同类型的变量 $a。

      if (isset($array['a']))
      {
          $a = $array['a']; // could be a string or anything else
      }
      else
      {
          $a = 1; // is an integer
      }
      

      对于后续代码中很容易成为问题的严格条件。 例如:假设$array['a'] 的值为'1'

      在犯规失败后:

      if ( $a === 1 ) // do something
      

      这里的类型和值必须匹配 TRUE 仅适用于上述其他情况 $a = 1;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-18
        • 1970-01-01
        • 1970-01-01
        • 2021-03-15
        相关资源
        最近更新 更多