За последние 24 часа нас посетили 21962 программиста и 1011 роботов. Сейчас ищут 705 программистов ...

фибоначи, рекурсия, анонимки

Тема в разделе "Решения, алгоритмы", создана пользователем AndreJM, 21 мар 2012.

  1. AndreJM

    AndreJM Активный пользователь

    С нами с:
    25 янв 2012
    Сообщения:
    522
    Симпатии:
    0
    Что-то в последнее время голова совсем не варит.
    Решил я по-тестировать работу анонимных функций. Ну конечно же для тестов взял самый простой алгоритм нахождения числа в последовательности фибоначи. Написал два разных алгоритма: с экспоненциальной сложностью (как раз то что нужно) и линейный. Кстати хотел еще и с циклами замутить но не стал. Оставил рекурсивный подход.
    Так вот.
    Ниже приведен код и результаты тестов. Или у меня совсем крыша съехала или мой комп тупит или код, но результаты какие-то противоречивые алгоритмам. Совершенно очевидно, что линейный быстрее но почему он же в анонимной функции медленнее экспоненциального собрата в анонимной функции, я вообще уже догнать не могу.
    Может кто-нить прогнать эти простенькие тесты и показать результаты?
    Заранее спасибо.
    И да может я просто не вижу в коде ошибку?
    Код (PHP):
    1. function fibr1($n,$k,$f,$f1){
    2.     return $k == $n $f : $k < $n ? fibr1($n, $k+1,$f+$f1,$f) : $f;
    3. }
    4. function fibr2($n){
    5.     return $n <= 1 ? 1 : fibr2($n-1)+fibr2($n-2);
    6. }
    7. $fib1 = function ($n, $k, $f, $f1) use (&$fib1) { 
    8.           return $k == $n $f : $k < $n $fib1($n, $k+1,$f+$f1,$f) : $f;
    9. };
    10. $fib2 = function($n) use (&$fib2) { 
    11.           return $n <= 1 ? 1 : $fib2($n-1)+$fib2($n-2);
    12. };
    13.  
    14. $count = 32;
    15.  
    16. $start = microtime(true);
    17. echo "Fib3 recurse1 +: " . fibr1($count,2,1,1) . PHP_EOL;
    18. echo "Fib3 recurse1 + time: " . ((microtime(true) - $start)) . PHP_EOL;
    19.  
    20. $start = microtime(true);
    21. echo "Fib4 recurse2 -: " . fibr2($count) . PHP_EOL;
    22. echo "Fib4 recurse2 - time: " . ((microtime(true) - $start)) . PHP_EOL;
    23.  
    24. $start = microtime(true);
    25. echo "Fib1 func +: " . $fib1($count,2,1,1) . PHP_EOL;
    26. echo "Fib1 func + time: " . ((microtime(true) - $start)) . PHP_EOL;
    27.  
    28. $start = microtime(true);
    29. echo "Fib2 func -: " . $fib2($count) . PHP_EOL;
    30. echo "Fib2 func - time: " . ((microtime(true) - $start)) . PHP_EOL;
    31.  
    Код (Text):
    1.  
    2. Fib3 recurse1 +: 3524578
    3. Fib3 recurse1 + time: 0.00017213821411133
    4. Fib4 recurse2 -: 3524578
    5. Fib4 recurse2 - time: 1.6537690162659
    6. Fib1 func +: 3524578
    7. Fib1 func + time: 3.0994415283203E-5
    8. Fib2 func -: 3524578
    9. Fib2 func - time: 2.5717799663544
    Заметил, что если тесты переставить местами то результаты реально расходятся.
     
  2. AndreJM

    AndreJM Активный пользователь

    С нами с:
    25 янв 2012
    Сообщения:
    522
    Симпатии:
    0
    Разделил тесты.
    Картина стала довольно ясная.
    Код (Text):
    1.  
    2. andrejm@andrejm:~/PHP$ php fib1.php
    3. Fib1 func +: 3524578
    4. Fib1 func + time: 0.00018310546875
    5.  
    6. andrejm@andrejm:~/PHP$ php fib2.php
    7. Fib2 func -: 3524578
    8. Fib2 func - time: 2.4435329437256
    9.  
    10. andrejm@andrejm:~/PHP$ php fibr1.php
    11. Fib3 recurse1 +: 3524578
    12. Fib3 recurse1 + time: 0.00016999244689941
    13.  
    14. andrejm@andrejm:~/PHP$ php fibr2.php
    15. Fib4 recurse2 -: 3524578
    16. Fib4 recurse2 - time: 1.6255810260773