在Scheme中是否有类似于Lisp中的"runtime"原语?

35
根据SICP第1.2.6节,练习1.22:

大多数Lisp实现都包括一个名为runtime的原语,它返回一个整数,指定系统运行的时间量(例如,以微秒为单位测量)。

我使用DrScheme,其中似乎没有可用的runtime,因此我正在寻找一个很好的替代品。我在PLT-Scheme参考中发现有一个current-milliseconds原语。有人知道是否有更高分辨率的Scheme计时器吗?

我刚好遇到了这个问题 :) - Chris Taylor
有趣的是,我正在使用Bill the Lizard的博客来检查我的答案,而他在4年前就已经完成了SICP。Lizard先生,您当初提出这个问题时是否预见到了这一点? - Cody Piersall
这里有一个使用racket的替代timed-prime-test的要点:https://gist.github.com/Isaac-Kleinman/1b623bc2463b241b4383 - Isaac Kleinman
5个回答

25

current-milliseconds 是一个函数,从系统中返回当前的毫秒计数,但它可能会减少。 current-inexact-milliseconds 类似,但返回保证增加的浮点数。

在该页面上还有许多类似的函数,但如果您只需要计算某个函数的时间,请使用 (time expr),它将打印出评估表达式所需的时间。

这里还有一件相关的事情是分析器,如果您需要更详细的分析代码。


5
首先,这是错误的。SICP和PLT之间没有直接关系。其次,毫秒计数器来自于操作系统,由于中断处理在几毫秒的级别上处理,使用更细的计数器没有意义。粒度通常在20毫秒左右,甚至不到1毫秒。如果你使用某些语言拥有纳秒计数器,也无法获得更好的结果。第三,以毫秒级别测量运行时间是一个不好的想法,你需要重复评估足够多的次数才能获得实质性的计数,否则运行时间将会被噪声淹没。 - Eli Barzilay
1
这里应该是 current-milliseconds 而不是 current-millisecond。我尝试编辑了答案,但是 Stack Overflow 要求编辑内容至少需要六个字符。 - bruno nery

6

今天我也遇到了这个问题。我正在使用DrRacket,因为它似乎已经取代了DrScheme。虽然这是一个旧的帖子,但我还是想分享我的发现,供新手参考。

如果选择R5RS (#lang r5rs)作为语言,在程序前添加以下两行代码即可使其正常运行

(#%require (only racket/base current-milliseconds))
(define (runtime) (current-milliseconds))

请问您能告诉我确切的 #lang ... 字符串吗?#lang R5RS 无法使用。 - Zelphir Kaltstahl
好的,我只是在书中代码不完整的“if”语句中添加了一个“else”分支,以便它在“#lang racket”中运行。 - Zelphir Kaltstahl
@Zelphir:我通常只是在DrRacket的左下角选择“R5RS”作为语言。那时候对我很有效。 - patentfox
1
它是 #lang r5rs - Oliver Tušla

2
您可以使用包含runtime定义的sicp包。 这里是该包的说明。 这里是包的描述。
这里是安装说明:
  • 打开软件包管理器:在DrRacket中,选择菜单文件,然后选择软件包管理器…

  • 在标签页Do What I Mean中找到文本框,输入:sicp

  • 最后点击安装按钮。

现在,您可以调用SICP中的runtime和其他过程。
#lang sicp
(runtime)

预期输出应该像这样:
1606611898030115
> 

1
我正在使用mit-scheme来学习SICP,并发现毫秒可以通过(real-time-clock)获得,具体请参考用户手册

1
如果您有符合2013年发布的Scheme编程语言修订版7算法语言Scheme报告(R7RS)的最新规范的实现,例如Chibi-Scheme,则应使用在R7RS中标准化的current-second时间库:

(current-second)时间库过程

返回表示国际原子时(TAI)上当前时间的不精确数字。值0.0表示1970年1月1日TAI午夜(相当于协调世界时午夜前十秒),值1.0表示一秒TAI之后。不需要高精度或高精度;特别地,返回协调世界时加上适当的常数可能是一个实现所能做到的最好的。

书籍计算机程序的构造和解释(SICP)的某些练习期望提供以微秒为单位测量的runtime过程,因此您可以使用以下定义:
(define (runtime) (* 1000 (current-second)))

OP想要比毫秒更好的分辨率;R7RS的jiffies可能有效,但是具体实现依赖于不同的情况。无论如何:“你现在应该使用current-second……”也许对于R7RS来说是这样,但是问题也被标记为[tag:racket];Racket不是R7RS。Racket在racket/base中有current-seconds(而不是R7RS中的current-second)和current-milliseconds。你仍然需要查看实现以获得良好的时间函数。许多人仍在使用R6RS,其中一个重要原因是Chez非常好。遗憾的是,Scheme社区在R6RS与R7RS之间分裂,但这仍然是现实生活的事实。 - ad absurdum
@adabsurdum 感谢您提供的信息,我之前不知道 Racket 不符合 R7RS 标准。我已经更新了我的回答。就我个人而言,我在 macOS 上使用 Chibi-Scheme,因为它符合 R7RS 标准并且可以在 Homebrew 上获取。 - Géry Ogam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接