Racket流是否会记忆它们的元素



Racket在计算无限流中的大量数字时是否使用内存化?例如,如果我打印出(也就是计算和显示)无限整数流上的前400个数字:(1 2 3…399 400)就在我要求把前500个数字打印在这个无限流上之后。第二组计算会使用记忆吗?那么前400个数字就不会再计算了?

或者该功能是否需要由用户编码/从库中获取?

内置的球拍/流库使用延迟求值和内存化从流中提取元素:

(require racket/stream)
(define (print-and-return x)
  (displayln "drawing element...")
  x)
(define (in-range-stream n m)
  (if (= n m)
      empty-stream
      (stream-cons (print-and-return n) (in-range-stream (add1 n) m))))
(define s (in-range-stream 5 10))
(stream-first s)
(stream-first s)
(stream-first (stream-rest s))

传递给CCD_ 1的表达式直到用CCD_ 2或CCD_。一旦评估,它们就会被记录下来。请注意,尽管在s上执行了四个流操作,但仅显示两条"drawing-element…"消息。

您可以使用memoize软件包。

GitHub来源:https://github.com/jbclements/memoize/tree/master

raco pkg install memoize

使用它就像用define/memo替换define一样简单。举个例子:

(define (fib n)                                     
  (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))  
> (time (fib 35))                                   
cpu time: 513 real time: 522 gc time: 0             
14930352                                            
> (define/memo (fib n)                              
    (if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))
> (time (fib 35))                                   
cpu time: 0 real time: 0 gc time: 0                 
14930352      

此外,使用Racket哈希表自己实现内存化通常很容易。

对于其他使用SRFI 41流的Scheme实现,这些流还完全存储了所有实体化元素。

事实上,在我的Guile端口SRFI 41(自2.0.9以来一直在Guile中)中,流的默认打印机将打印出所有如此具体化的元素(没有):

scheme@(guile-user)> ,use (srfi srfi-41)
scheme@(guile-user)> (define str (stream-from 0))
scheme@(guile-user)> (stream-ref str 4)
$1 = 4
scheme@(guile-user)> str
$2 = #<stream ? ? ? ? 4 ...>

任何未打印为?stream-cons0的元素都已被存储,不会重新计算。(如果你想知道如何实现这样的打印机,这里是Guile版本。)

相关内容

  • 没有找到相关文章