【问题标题】:Stack overflow using hhvm for benchmarkgame adapted to strict Hack使用 hhvm 进行堆栈溢出以适应严格的 Hack
【发布时间】:2015-06-28 21:49:39
【问题描述】:

由于 Hack 在严格模式下更快,我尝试将第一个 benchmarkgame 转换为 dito,但遇到了在非严格版本中从未发生过的堆栈溢出(与使用对象的递归调用不同?)。有什么理由吗?我怎样才能增加堆栈大小?正如您可以想象的那样,在谷歌上搜索“php 堆栈溢出”是没有用的。 ^^

问题发生在第一次递归调用上。

我的代码:

<?hh // strict

class Tree {
  public function bottomUpTree(?num $item, ?num $depth) : array<?num>
  {
    if ($depth === null) return array(null,null,$item);
    if ($item !== null) {
      $item2 = $item + $item;
      $depth--;
      return array( // <--- Stack overflow here
        $this->bottomUpTree($item2-1,$depth),
        $this->bottomUpTree($item2,$depth),
        $item);
    }
    else {
      throw new Exception("Fatal");
    }
  }

  public function itemCheck(array<?int, ?int> $treeNode) : int {
    if ($treeNode !== null && $treeNode[2] !== null) {
      $someNumber = $treeNode[2];
      $a = $someNumber + 10;
      return $someNumber
        + ($treeNode[0][0] === null ? $this->itemCheck($treeNode[0]) : $treeNode[0][2])
        - ($treeNode[1][0] === null ? $this->itemCheck($treeNode[1]) : $treeNode[1][2]);
    }
    else {
      throw new Exception("Fatal");
    }
  }

  public function run($argc, $argv) {

    $minDepth = 4;

    $n = ($argc == 2) ? $argv[1] : 1;
    $maxDepth = max($minDepth + 2, $n);
    $stretchDepth = $maxDepth + 1;

    $stretchTree = $this->bottomUpTree(0, $stretchDepth);
    printf("stretch tree of depth %d\t check: %d\n",
      $stretchDepth, $this->itemCheck($stretchTree));
    unset($stretchTree);

    $longLivedTree = $this->bottomUpTree(0, $maxDepth);

    $iterations = 1 << ($maxDepth);
    do {
      $check = 0;
      for($i = 1; $i <= $iterations; ++$i)
      {
        $t = $this->bottomUpTree($i, $minDepth);
        $check += $this->itemCheck($t);
        unset($t);
        $t = $this->bottomUpTree(-$i, $minDepth);
        $check += $this->itemCheck($t);
        unset($t);
      }

      printf("%d\t trees of depth %d\t check: %d\n", $iterations<<1, $minDepth, $check);

      $minDepth += 2;
      $iterations >>= 2;
    }
    while($minDepth <= $maxDepth);

    printf("long lived tree of depth %d\t check: %d\n",
      $maxDepth, $this->itemCheck($longLivedTree));
  }
}

$tree = new Tree();
$tree->run($argc, $argv);

【问题讨论】:

  • 除了您提出的问题之外,还有一些关于代码的 cmets。首先,您应该考虑使用元组而不是数组作为 bottomUpTree 的返回值。其次,“严格 Hack 中的代码更快”的概念并不那么简单(并且忽略了 Hack 是关于开发人员效率而不是代码效率的观点),请参阅我在其他地方的回答:stackoverflow.com/a/26100185/3395144

标签: php stack-overflow hhvm hacklang


【解决方案1】:

您的递归永远不会遇到基本情况并停止,因为您在递归时传递的值永远不会为空。

如果$depth 为0 以及null,您可能想退出。

【讨论】:

  • 当然!原始代码是!$depth,但 hack 不喜欢这样。你是对的,谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2021-05-28
  • 1970-01-01
  • 2017-07-02
相关资源
最近更新 更多