【翻译】Go 编译器理解: 新增一个关键字语句-Part2
这是介绍Go编译器系列的第二篇,在第1部分中,我们在Go中添加了一个新的关键词语句,通过构建修改版本的编译器来支持该关键字。为此,我们按照此图介绍了编译器的前五个阶段:

在最后,我们是通过在"重写AST"阶段将其替换为for来实现until。另外,在gc/walk.go中,其他类似的转换也是在编译器进行SSA转换和代码生成之前完成的。
在这一部分中,我们将通过在编译流程中处理新的until语句来介绍编译器的其余阶段。
这是介绍Go编译器系列的第二篇,在第1部分中,我们在Go中添加了一个新的关键词语句,通过构建修改版本的编译器来支持该关键字。为此,我们按照此图介绍了编译器的前五个阶段:

在最后,我们是通过在"重写AST"阶段将其替换为for来实现until。另外,在gc/walk.go中,其他类似的转换也是在编译器进行SSA转换和代码生成之前完成的。
在这一部分中,我们将通过在编译流程中处理新的until语句来介绍编译器的其余阶段。
原文发表在 thegreenplace,推荐观看原文Go compiler internals: adding a new statement to Go - Part 1 - Eli Bendersky’s website (thegreenplace.net)
这是该系列第一篇文章,文章将简单介绍Go 的编译器。编译器知识非常庞大,一般需要一本书才能详细描述。因此本文章只是一个快速的叫深入的介绍。我计划未来写更多的关于编译器的文章。
在本系列中,我们将向Go编译器中添加一个新的语言关键字,建立一个可修改的编译器。(译者注:Go实现了自举,因此Go编译器也其实是一个Go应用,只要理解其中的原理,添加一个新的关键字特性也并非难事)
本文实现了一个介于wait-free 和 lock-free的高性能MPSC队列,也就是多生产者但消费者队列。
与使用channel耗时测试:
测试配置:1W个生产者,每个生产者写入90次。统计生产者全部写入队列耗时。
| 测试 | MPSC队列耗时 | channel耗时 |
|---|---|---|
| 测试1 | 115.454185ms | 965.9469ms |
| 测试2 | 97.00209ms | 992.595ms |
| 测试3 | 109.776455ms | 989.837ms |
| 测试4 | 90.19232ms | 1.3611857s |
| 测试5 | 79.12408ms | 1.2725355s |
| 测试6 | 68.650755ms | 1.3981461s |
| 测试7 | 77.155775ms | 1.2469043s |
| 测试8 | 103.899735ms | 1.4227174s |
| 测试9 | 72.15339ms | 1.3351006s |
| 测试10 | 129.974485ms | 1.0454128s |
测试的重要性不言而喻。然而在项目中,真正做到编写完整的测试却是少之又少。
主要原因推测有三个:
一般的测试分为单元测试和集成测试,但是这里我们会模糊这种界限,不做具体区分。下面出现的代码都是为了这篇文章而写的伪代码,没有考虑架构之类的。
编程中常用的、易忘的配置等记录
四年前,我写了一篇名为”Standard Package Layout“的文章,试图解决即使是高级Go开发人员最困难的主题之一:package layout(go项目中包的组织)。 但是,大多数开发人员仍在努力用目录的方式组织管理代码。
几乎所有的编程语言都有一种将相关功能分组在一起的机制。 Ruby有gems,Java有packages。 这些语言没有将代码代码分组的标准约定,因为老实说,这并不重要。 一切都取决于个人喜好。
但是,转到Go的开发人员发现他们需要经常关心代码包的组织。 为什么Go软件包与其他语言如此不同? 这是因为它们不是groups(组),而是layers(层)。
增删改查(CRUD)是一个技术产品的基础部分,做过应用开发的人应该很熟悉它。
开发CRUD应用时,大多数编程语言会有框架提供一个固定的开发架构,例如PHP的Yii2、Java的SSH。但是总所周知Go社区是反框架的。因此,我们需要设计自己的CRUD架构。
在一年的Go应用开发经验后,我发现了一套通用的CRUD设计模式,能满足大多数不同的项目的要求。我将以开发 WTF Dial 项目为例进行说明。 项目的详细介绍参考链接。
译者:WTF Dial(which they feel) 项目提供一个界面,每个成员可输入对当前团队的糟糕程度(f-cked)。