常规递归和尾递归的性能比较

来源:互联网 发布:药品数据 编辑:程序博客网 时间:2024/05/21 08:46
package net.liuyx.algorithm;public class Fibonacci {    private static int[][] a = { { 1, 1 }, { 1, 0 } };    /**     * @param args     */    public static void main(String[] args) {        for (Tester test : tests)            test.test(80);    }    private static Tester[] tests = {/* new Tester("常规递归") {        @Override        long fib(int n) {            if (n < 2)                return n;            return fib(n - 1) + fib(n - 2);        }    }, */new Tester("尾递归") {        @Override        long fib(int n) {            return fib2(n, 1, 1);        }        private long fib2(int n, int acc1, int acc2) {            if (n < 2)                return acc1;            return fib2(n - 1, acc2, acc1 + acc2);        }    }, new Tester("尾递归转换成循环性") {        @Override        long fib(int n) {            int acc1 = 0, acc2 = 1;            while (true) {                if (n == 0) {                    return acc1;                }                if (n == 1)                    return acc2;                int tmp = acc1;                acc1 = acc2;                acc2 = acc2 + tmp;                n--;            }        }    }, new Tester("经过算法优化的 ") {        @Override        long fib(int n) {            int[][] arr = fibonacciAlogrithm(n);            long result = arr[1][1];            return result;        }        private int[][] fibonacciAlogrithm(int n) {            int[][] result = { { 1, 1 }, { 1, 0 } };            while (n != 0) {                if ((n & 1) != 0) {                    result = multiply(result, a);                }                a = multiply(a, a);                n = n >> 1;            }            return result;        }        private int[][] multiply(int[][] a, int[][] b) {            int[][] result = new int[2][2];            result[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0];            result[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1];            result[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0];            result[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1];            return result;        }    } };    private static abstract class Tester {        private String name;        public Tester(String name) {            this.name = name;        }        public void test(int n) {            System.out.print(name + ": ");            long start = System.nanoTime();            fib(n);            long duration = System.nanoTime() - start;            System.out.println("历时: " + duration);        }        abstract long fib(int n);    }}

结果: