【发布时间】:2019-09-30 11:48:35
【问题描述】:
我实现了一个简单但不是很有效的 Eratosthenes 筛子。一次用于内置球拍流,一次用于自定义流。对我而言,唯一已知的区别是内置流正在评估第一个待命项目,而不是在施工中。在两种实现上评估前 1000 个素数时,自定义流的运行速度提高了 10-20 倍。有什么解释吗?
(define (integers-starting-from-stream n)
(stream-cons n (integers-starting-from-stream (+ n 1))))
(define (stream-limit s limit)
(when (not (= limit 0)) (stream-limit (stream-rest s) (- limit 1))))
(define x (integers-starting-from-stream 2))
(define (divisible? x y)
(= (remainder x y) 0))
(define (sieve s)
(stream-cons
(stream-first s)
(sieve (stream-filter
(lambda (x)
(not (divisible? x (stream-first s))))
(stream-rest s)))))
(time (stream-limit (sieve x) 1000))
或者我错过了影响性能的东西?
(define-syntax-rule (s-delay exp)
(λ() exp))
(define (s-force delayedObject)
(delayedObject))
(define empty-s 'S-EMPTY-STREAM)
(define (s-empty? s)
(eq? s empty-s))
(define (s-first s)
(car s))
(define (s-rest s)
(s-force (cdr s)))
(define-syntax-rule (s-cons a b)
(cons a (s-delay b)))
(define (s-filter p s)
(cond ((s-empty? s) empty-s)
((p (s-first s))
(s-cons (s-first s)
(s-filter p (s-rest s))))
(else (s-filter p (s-rest s)))))
;;;;;;;;;;;;;;;;;;;;
(define (divisible? x y)
(= (remainder x y) 0))
(define (integers-starting-from n)
(s-cons n (integers-starting-from (+ n 1))))
(define (s-limit s limit)
(when (not (= limit 0)) (s-limit (s-rest s) (- limit 1))))
(define x (integers-starting-from 2))
(define (sieve s)
(s-cons (s-first s) (sieve (s-filter (lambda(x) (not (divisible? x (s-first s)))) (s-rest s)))))
(time (s-limit (sieve x) 1000))
【问题讨论】:
-
我假设您正在运行已编译的代码。我已经玩了一点,虽然你的实现跳过了记忆和懒惰
car,但如果我添加它,我只会慢 5 倍。我最好的猜测是 JIT 设法不断折叠本地代码,当它在自己的模块中时可能不太好。您可能对how to look at what the jit has done 感兴趣 -
@Alex 你能发布一个可以运行的示例,以便我们自己尝试基准测试吗?
-
@soegaard 他们应该准备好运行了,你只需在顶部添加#lang racket。
-
我无法提供任何解决方案或答案,但我可以确认 Eratosthenes 筛的 Racket 流实现非常缓慢、令人无法接受!您使用的算法非常标准(参见例如 SICP);比较它,例如对于 MIT-Scheme,找到第 500 个素数时速度要慢 100 倍! i7 3分钟?真的吗?将其与 Clojure 进行比较只会导致绝望。我认为有些严重的错误。不能按原样使用。但也许我们都遗漏了一些明显的东西......
-
这不仅仅是速度。空间需求也很荒谬。必须将内存限制设置为 4096 MB 才能计算出第 500 个素数 (3581)。我会在某个阶段对其进行研究,但就目前而言,它并不真正适合目的。
标签: performance racket sieve-of-eratosthenes