;;; expt1 : Real NonNegInt -> Real
;;; expt2 : Real NonNegInt -> Real
;;; Given x and n, returns x raised to the nth power.
(define (expt1 x n) ; the obvious Θ(n) algorithm
(if (= n 0)
1
(* x (expt1 x (- n 1)))))
(define (expt2 x n) ; the divide-and-conquer algorithm
(define (square x)
(* x x))
(cond ((= n 0)
1)
((even? n)
(square (expt2 x (quotient n 2))))
(else
(* x (square (expt2 x (quotient n 2)))))))
On my laptop, which is an early 2015 MacBook with a 1.1 GHz Intel Core M processor:
> (define x (time (expt1 3 100000)))
Elapsed time...: 4139 ms
> (define y (time (expt2 3 100000)))
Elapsed time...: 163 ms
> (define z (time (expt 3 100000)))
Elapsed time...: 165 ms
So the divide-and-conquer algorithm is about 25 times as fast
as the obvious algorithm on this benchmark, and is just as fast
as the predefined expt function.
What algorithm do you think the predefined expt
function is using?