计算机程序的构造和解释 练习题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倍。基本符合我们的猜想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值