Scheme 参数传入方案的成本
我发现了一件有趣的事。通过辩论可能值得考虑,特别是在时间很重要的情况下。代码如下所示Scheme 参数传入方案的成本,scheme,argument-passing,Scheme,Argument Passing,我发现了一件有趣的事。通过辩论可能值得考虑,特别是在时间很重要的情况下。代码如下所示 (define (collatz-num n) (define (collatz-iter n m) (cond ((= n 1) m) ((even? n) (collatz-iter (/ n 2) (+ m 1))) (else (collatz-iter (+ (* 3 n) 1) (+ m 1))))) (collatz
(define (collatz-num n)
(define (collatz-iter n m)
(cond
((= n 1)
m)
((even? n)
(collatz-iter (/ n 2) (+ m 1)))
(else
(collatz-iter (+ (* 3 n) 1) (+ m 1)))))
(collatz-iter n 1))
(define (collatz-iter n m)
(cond
((= n 1)
m)
((even? n)
(collatz-iter (/ n 2) (+ m 1)))
(else
(collatz-iter (+ (* 3 n) 1) (+ m 1)))))
(define (euler14 n limit)
(define (help-iter m len n limit)
(let ((collatz (collatz-iter n 1)))
(cond
((> n limit)
(list m len))
((> collatz len)
(help-iter n collatz (+ n 2) limit))
(else
(help-iter m len (+ n 2) limit)))))
(help-iter 0 0 n limit))
用于科拉兹iter
对于collatz num
我的问题:
在方案中通过论证的成本有多大
在函数euler14中,我让limit作为help iter的参数,这样会节省一些时间吗?正如我在某处看到的,自由变量将有成本
也许我太小气了。再说一遍。这是非常具体的实现 我测试了你的代码,因为它确实消耗内存并进行了大量计算,所以我测试这两个代码的顺序干扰了第二个结果。我将每个文件中的两个测试分开,分别运行40次,并查看两个文件的平均运行时间。差异为num:1059.75和iter:1018.85。平均差异为4%,但在选取两个样本时,差异也可能为12%。我猜同一个程序的运行时间可能平均相差4%以上,所以在一次运行中,它们之间的差异是不相关的 您的代码中有一个额外的应用程序,以便检查我进行的这个小测试对参数的影响有多大。基本情况中参数的使用是为了使Scheme不会优化它们:
(define (three-params x y z)
(if (zero? x)
(cons y z)
(three-params (- x 1) x x)))
(define (two-params x y)
(if (zero? x)
(cons x y)
(two-params (- x 1) x)))
(define (one-param x)
(if (zero? x)
(cons x x)
(one-param (- x 1))))
(define numtimes 100000000)
(time (one-param numtimes))
(time (two-params numtimes #f))
(time (three-params numtimes #f #f))
注释掉最后三行中的2行,创建3个文件。如果可以,请编译它们。
平均数为几次。我选择50,在Ikarus中,我得到以下平均值:
agvms diffms
one 402.4
two 417.82 15.42
three 433.14 15.32
two2 551.38 133.56 (with an extra addition compared to two)
仅看50个结果,我发现时间在1、2和3之间重叠,但从统计上看,平均争论成本为0,15ns。if,zero?,-和cons以及gc即使是原语,成本也要高得多。您不应该担心额外的应用程序或额外的参数。有时,不同的实现会以不同的方式优化代码,因此从racket更改为ikarus,gambit或chicken可能会在生产中改进您的代码。您有问题吗?我更新了这个问题。有人回答了您之前关于性能的问题并使您满意吗?与以前一样的评论:这种微优化不值得您花费时间,最好考虑降低算法复杂性或缓存结果。并使用剖析器,找出问题的真正所在。@Óscar López,好建议。昨晚我想,我可以做更多的事情来减少花费的时间,而不是纠缠在这个问题上。非常专业。我认为在第三行和第二行中,逗号是句号。实际上,这并不重要。我只是好奇。我应该学习更多关于Scheme编译器的知识。ikarus还在开发中吗?我发现它的最后一个日期是2008@kuan291固定的创作者Abdulaziz Ghuloum自2010年以来一直没有做过任何事情,所以你对停止开发的看法是正确的,但是0.0.4可能比0.0.3好,即使它没有正式发布,它也是Ubuntu发布的。还有待观察Ikarus是否会支持当前的标准R7RS,但这与我对其他实现的问题相同。Ikarus方案是例外。
(define (three-params x y z)
(if (zero? x)
(cons y z)
(three-params (- x 1) x x)))
(define (two-params x y)
(if (zero? x)
(cons x y)
(two-params (- x 1) x)))
(define (one-param x)
(if (zero? x)
(cons x x)
(one-param (- x 1))))
(define numtimes 100000000)
(time (one-param numtimes))
(time (two-params numtimes #f))
(time (three-params numtimes #f #f))
agvms diffms
one 402.4
two 417.82 15.42
three 433.14 15.32
two2 551.38 133.56 (with an extra addition compared to two)