使用 hhvm 进行堆栈溢出以适应严格的 Hack 基准游戏
Stack overflow using hhvm for benchmarkgame adapted to strict Hack
由于 Hack 在严格模式下速度更快,我尝试将第一个 benchmarkgame 转换为 dito,但卡在堆栈溢出上,这在非严格版本中从未发生过(与使用对象的递归调用不同) ?)。有什么理由吗?我怎样才能增加堆栈大小?谷歌搜索 "php stack overflow" 是无用的,正如您可以想象的那样。 ^^
第一次递归调用时出现问题。
我的代码:
<?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);
您的递归永远不会遇到基本情况并停止,因为递归时传递的值永远不会为空。
如果 $depth
为 0 以及 null
,您可能希望退出。
由于 Hack 在严格模式下速度更快,我尝试将第一个 benchmarkgame 转换为 dito,但卡在堆栈溢出上,这在非严格版本中从未发生过(与使用对象的递归调用不同) ?)。有什么理由吗?我怎样才能增加堆栈大小?谷歌搜索 "php stack overflow" 是无用的,正如您可以想象的那样。 ^^
第一次递归调用时出现问题。
我的代码:
<?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);
您的递归永远不会遇到基本情况并停止,因为递归时传递的值永远不会为空。
如果 $depth
为 0 以及 null
,您可能希望退出。