|
|
1
5
以下是Kent Dybvig的回复: 这是个有趣的问题。 当使用--script(使用REPL语义)运行时,变量 脚本中定义的列表枚举和列表索引是可变的, 它抑制了过程间的优化,包括内联。什么时候? 但是,变量是不可变的,这允许 程序间优化。 在这种情况下,--程序允许编译器将列表枚举内联到 列表索引的主体,然后是列表索引中的lambda表达式 body into list枚举的body。最终结果是有条件的 调用中的表达式,值为producer表达式。这会导致 编译器为使用者创建一个闭包,以避免代码 沿着条件的then和else分支重复。这个 每次通过list枚举的循环创建闭包,结果 额外的分配开销。这就是优化经常采用的方式。 多数情况下你赢了,但有时你输了。好消息是,总的来说 即使在你的项目中,收益也大于成本。我打电话给 在循环中列出索引(修改后的代码如下),并发现 --程序,代码运行速度大约快30%。 肯特 (import (chezscheme))
(define (list-enumerate ls val proc)
(let loop ((ls ls) (return? #f) (val val))
(if (or (null? ls)
return?)
val
(call-with-values (lambda () (proc val (car ls)))
(lambda (return? val)
(loop (cdr ls) return? val))))))
(define (list-index ls proc)
(list-enumerate ls
0
(lambda (i elt)
(if (proc elt)
(values #t i)
(values #f (+ i 1))))))
(define n 100000)
(define data (time (iota n)))
(let ()
(define runalot
(lambda (i thunk)
(let loop ([i i])
(let ([x (thunk)])
(if (fx= i 1)
x
(loop (fx- i 1)))))))
(time
(runalot 1000
(lambda ()
(list-index data (lambda (elt) (= elt (- n 1))))))))
|