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)