【问题标题】:What is a perfomance penalty for single token lookahead?单令牌前瞻的性能损失是多少?
【发布时间】:2015-01-28 07:21:44
【问题描述】:

比较 Go 和 Scala 的语句结束检测,发现 Scala 的规则更丰富,即:

行尾被视为分号,除非出现以下情况之一 条件为真:

  • 有问题的行以一个作为语句结尾不合法的单词结尾,例如句点或中缀运算符。
  • 下一行以一个不能启动语句的单词开头。
  • 该行在括号 (...) 或方括号 [...] 内结束,因为它们不能包含多个语句。

引用自Scala - The rules of semicolon inference

规则 #1 也是 Go 的工作方式。规则#3也是。唯一的区别是规则 #2 - 它涉及单次前瞻,因为涉及一个标记(“单词”)。

涉及什么样的性能损失:慢 1%、5%、10%?

我很想看到一条评论(不是问题)为什么 Go 设计者忽略了这条规则——如果不是为了性能,它会让语言更可靠,例如在方法链中:

x = some_object.select(...)
               .sort(...)
               .reverse(...)
               .where(...)
               .single()

如果我没有误认为 Go,那是一个错误(您可以通过两种可能的方式解决它——将整个语句放在大括号中或将表达式放在括号中,但它是手动调整的),Scala 会按照它应该的方式处理。

【问题讨论】:

    标签: scala go syntax


    【解决方案1】:

    与编译器必须做的其他事情相比,性能损失完全可以忽略不计。 Scala-internals 邮件列表中有 Haoyi Li 和 Martin Odersky 之间关于 Haoyi 为 Scala 编写的 parboiled2 解析器的以下交流:

    李浩毅:在性能方面,它可以在 15 秒内解析 scala/scala、lift、scalaz、scalajs、playframework 和 shapeless 中的所有内容....有谁知道如何编译器和宏中的大部分时间都花在解析上?我的印象是,绝大多数时间都花在了类型检查器上。

    Odersky:是的,与编译器的其他任务相比,解析是微不足道的……也就是说,[下一代 Scala 编译器的解析器](手写,2100 行,包括错误报告、准确的位置和树构建)达到每秒几十万行。所以半熟仍然有一些方法可以打败它:-)

    当我们谈论每秒解析数十万行代码时包括规则#2,我们可以推断出速度不是问题。 Go 编译倾向于以每秒around 20k lines 的速度进行,因此即使 Go 解析花费了零时间,并且 Scala 解析的整个时间被单行前瞻占用,它也会更少对构建过程的惩罚超过 10%。

    实际上它应该更像是 0%。 Lookahead 通常非常便宜。您已经获得了一个令牌流,所以您只需查看下一个。

    【讨论】:

    • 非常感谢您提供的信息丰富的回答。考虑到您提供的数据,我真的很惊讶 Go 设计者没有考虑下一行——它让生活更轻松。
    【解决方案2】:

    似乎如果行以任何内容开头,但语句编译器会抱怨。你也可以在 Go 中链接方法 https://play.golang.org/p/h8NYnBXjFI

    【讨论】:

    • 是的,我知道你可以链接方法,但是 Go 再次让人类为计算机需求工作。这只是一种奇怪的方法(如果你问我的话)。
    猜你喜欢
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-11
    • 2012-01-04
    • 1970-01-01
    • 2011-06-09
    • 2023-02-23
    • 1970-01-01
    相关资源
    最近更新 更多