计算机程序的构造和解释 练习题1.23

重新定义一个过程next如下:

(define (next test-divisor)
  (if(= test-divisor 2) 3 (+ test-divisor 2)))
))

然后重新运行练习1.22的结果

#lang racket
(define (next test-divisor)
  (if(= test-divisor 2) 3 (+ test-divisor 2)))
(define (square x) (* x x))
(define (runtime) ( current-inexact-milliseconds )) 
(define(smallest-divisor n)
	(find-divisor n 2))
(define(find-divisor n test-divisor)
	(cond((>(square test-divisor) n ) n)
		((divides? test-divisor n) test-divisor)
		(else(find-divisor n (next test-divisor)))))

(define(divides? a b)
	(=(remainder b a) 0))
(define (prime? n)
	(= n (smallest-divisor n)))

(define (timed-prime-test n) 
	(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
	(if (prime? n)
		(begin (report-prime n (- (runtime) start-time)) #t) #f))
(define(report-prime n elapsed-time)
  	(newline)
        (display n)
	(display " usetime ")
	(display elapsed-time))
	
(define (search-for-primes n count)
  (cond((= count 0) n )
  ((timed-prime-test n) (search-for-primes (+ n 1) (- count 1)))
    (else (search-for-primes (+ n 1) count))))

(search-for-primes 1000000000 3)
(search-for-primes 10000000000 3)
(search-for-primes 100000000000 3)
(search-for-primes 1000000000000 3)
(search-for-primes 10000000000000 3)

运行结果

1000000007 usetime 0.9990234375
1000000009 usetime 1.9990234375
1000000021 usetime 0.9992675781251000000022

10000000019 usetime 3.997802734375
10000000033 usetime 3.9970703125
10000000061 usetime 3.98315429687510000000062

100000000003 usetime 14.002197265625
100000000019 usetime 13.98291015625
100000000057 usetime 14.00146484375100000000058

1000000000039 usetime 44.974609375
1000000000061 usetime 48.972412109375
1000000000063 usetime 47.9645996093751000000000064

10000000000037 usetime 192.888671875
10000000000051 usetime 154.90087890625
10000000000099 usetime 150.9135742187510000000000100

运行结果和之前的结果进行比较,比值大概在1.6-1.7之间,我觉得原因应该是我们只对主要的计算过程进行了优化,使其减少了一半的计算次数,但是我们增加了一次函数调用和一次if逻辑判断,这个可能是影响的原因之一。
为了验证我们的猜想,把if判断移到smallest-divisor过程中判断,减少if判断次数,然后去掉next函数,直接用(+ test-divisor 2)来代替。

(define(smallest-divisor n)
  (if (divides? 2 n) 2 (find-divisor n 3)))
(define(find-divisor n test-divisor)
	(cond((>(square test-divisor) n ) n)
		((divides? test-divisor n) test-divisor)
		(else(find-divisor n (+ test-divisor 2)))))

运行结果:

1000000007 usetime 1.998779296875
1000000009 usetime 1.0087890625
1000000021 usetime 0.9997558593751000000022

10000000019 usetime 4.997314453125
10000000033 usetime 2.998291015625
10000000061 usetime 3.9975585937510000000062

100000000003 usetime 11.992919921875
100000000019 usetime 10.99365234375
100000000057 usetime 13.0068359375100000000058

1000000000039 usetime 35.974609375
1000000000061 usetime 41.9814453125
1000000000063 usetime 41.9899902343751000000000064

10000000000037 usetime 114.928955078125
10000000000051 usetime 128.916748046875
10000000000099 usetime 127.926757812510000000000100

两次运行结果的比值基本接近2倍。基本符合我们的猜想。

发布了27 篇原创文章 · 获赞 1 · 访问量 482

猜你喜欢

转载自blog.csdn.net/holybird0213/article/details/104604795