drxpt06820 2012-11-30 03:10
浏览 201
已采纳

PHP中的尾递归慢于正常递归?

I did up 2 versions of a factorial function in PHP for benchmarking, one using normal recursion, the other using tail recursion. The latter should be faster but results show otherwise. Am I missing anything here?

My code is as follows, including the benchmark test:

<?php
benchmark();

function benchmark()
{
    $n = 10;
    $multiplier = 10000;
    $functions = array('factorial_recursive', 'factorial_tailRecursive');

    foreach ($functions as $function) {
        $start = microtime(true);
        echo $function . '<br>';
        echo $function($n) . '<br>';
        echo ($multiplier * (microtime(true) - $start)) . '<br><br>';
    }
}

function factorial_recursive($n)
{
    if ($n == 1) {
        return $n;
    }

    return $n * factorial_recursive($n - 1);
}

function factorial_tailRecursive($n, $result = 1)
{
    if ($n == 1) {
        return $result;
    }

    return factorial_tailRecursive($n - 1, $result * $n);
}

Printed output:

factorial_recursive
3628800
2.4199485778809

factorial_tailRecursive
3628800
2.5296211242676

Any insight appreciated - thanks!

  • 写回答

1条回答 默认 最新

  • doulongsi1831 2012-11-30 04:00
    关注

    I took your code and modified it slightly for running on the command line (converted br's to newlines, tweaked the output format). Also, I changed it so that benchmark is run for 25 iterations instead of just one:

    <?php
    foreach (range(1, 25) as $iteration) {
        benchmark($iteration);
    }
    
    function benchmark($iteration)
    {
        $n = 10;
        $multiplier = 10000;
        $functions = array('factorial_recursive', 'factorial_tailRecursive');
    
        echo "
    Iteration {$iteration}:
    ";
        foreach ($functions as $function) {
            $start = microtime(true);
            echo $function . "
    ";
            echo $function($n) . "
    ";
            echo ($multiplier * (microtime(true) - $start)) . "
    
    ";
        }
    }
    
    function factorial_recursive($n)
    {
        if ($n == 1) {
            return $n;
        }
    
        return $n * factorial_recursive($n - 1);
    }
    
    function factorial_tailRecursive($n, $result = 1)
    {
        if ($n == 1) {
            return $result;
        }
    
        return factorial_tailRecursive($n - 1, $result * $n);
    }
    

    Here is my php cli version:

    $ php --version
    PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli) (built: Sep 12 2012 19:00:43) 
    Copyright (c) 1997-2012 The PHP Group
    Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
        with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
    

    Here are the results of my 25 iterations:

    $ php ./benchmark.php 
    
    Iteration 1:
    factorial_recursive
    3628800
    0.46014785766602
    
    factorial_tailRecursive
    3628800
    0.33855438232422
    
    
    Iteration 2:
    factorial_recursive
    3628800
    0.26941299438477
    
    factorial_tailRecursive
    3628800
    0.26941299438477
    
    
    Iteration 3:
    factorial_recursive
    3628800
    0.27179718017578
    
    factorial_tailRecursive
    3628800
    0.2598762512207
    
    
    Iteration 4:
    factorial_recursive
    3628800
    0.26941299438477
    
    factorial_tailRecursive
    3628800
    0.2598762512207
    
    
    Iteration 5:
    factorial_recursive
    3628800
    0.28848648071289
    
    factorial_tailRecursive
    3628800
    0.28848648071289
    
    
    Iteration 6:
    factorial_recursive
    3628800
    0.27894973754883
    
    factorial_tailRecursive
    3628800
    0.27894973754883
    
    
    Iteration 7:
    factorial_recursive
    3628800
    0.29087066650391
    
    factorial_tailRecursive
    3628800
    0.2598762512207
    
    
    Iteration 8:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.25033950805664
    
    
    Iteration 9:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.2598762512207
    
    
    Iteration 10:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.24795532226562
    
    
    Iteration 11:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.27894973754883
    
    
    Iteration 12:
    factorial_recursive
    3628800
    0.27894973754883
    
    factorial_tailRecursive
    3628800
    0.27894973754883
    
    
    Iteration 13:
    factorial_recursive
    3628800
    0.2598762512207
    
    factorial_tailRecursive
    3628800
    0.25033950805664
    
    
    Iteration 14:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.27179718017578
    
    
    Iteration 15:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.24795532226562
    
    
    Iteration 16:
    factorial_recursive
    3628800
    0.24080276489258
    
    factorial_tailRecursive
    3628800
    0.25033950805664
    
    
    Iteration 17:
    factorial_recursive
    3628800
    0.27179718017578
    
    factorial_tailRecursive
    3628800
    0.25033950805664
    
    
    Iteration 18:
    factorial_recursive
    3628800
    0.24080276489258
    
    factorial_tailRecursive
    3628800
    0.25033950805664
    
    
    Iteration 19:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.25033950805664
    
    
    Iteration 20:
    factorial_recursive
    3628800
    0.25033950805664
    
    factorial_tailRecursive
    3628800
    0.2598762512207
    
    
    Iteration 21:
    factorial_recursive
    3628800
    0.24795532226562
    
    factorial_tailRecursive
    3628800
    0.23841857910156
    
    
    Iteration 22:
    factorial_recursive
    3628800
    0.30040740966797
    
    factorial_tailRecursive
    3628800
    0.29087066650391
    
    
    Iteration 23:
    factorial_recursive
    3628800
    0.30994415283203
    
    factorial_tailRecursive
    3628800
    0.26226043701172
    
    
    Iteration 24:
    factorial_recursive
    3628800
    0.29087066650391
    
    factorial_tailRecursive
    3628800
    0.32186508178711
    
    
    Iteration 25:
    factorial_recursive
    3628800
    0.27894973754883
    
    factorial_tailRecursive
    3628800
    0.30040740966797
    

    Looking at these results, I'd have to say the difference is negligible, too close to call. They're effectively identical in runtime, at least in terms of Big-O.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)