一个“更好的C”基准

2021-03-28 18:14:07

C差不多50岁。一瓶葡萄酒的一个伟大的年龄,在快速移动行业中的编程语言不太伟大。在过去的10年里,许多新语言已经出现了不同的口味,所有人都试图在一定程度上成为C替代品。

当新语言变得或多或少受欢迎的流行开发人员开始编写基准时,显示这种语言中的软件是多么表现,CPU功率和多少内存是多少,二进制文件有多大。

在这里,我想在不同的飞机上进行一点实验 - UX的编程语言,开发人员的效率如何是使用这个或那种语言,使用它们是多么容易,有什么常见的挫折,人们如何感受他们读了代码。我认为,编程语言的UX与他们的技术特征一样重要,并且它有很大贡献了一种语言的成功。

让我们写一个应用程序,该应用程序在当前目录中递归递归播放,并在与给定通配符匹配的文件中打印这些行。像AG或Grep这样的东西,但使用通配符而不是正则表达式。应该忽略二进制文件。

我发现这个问题是一个很好的练习,因为它显示了如何实现一个非常简单的通配符匹配算法(它适用于纯数据,如字符串和数字,无需学习任何库或API)。该算法应通过一些非常简单的测试。然后它需要一些非常常见的,但低级的API,例如递归扫描目录或按行读取文件行。问题的所有部分都非常简单,小而且很好。我认为,即使没有以前的经验,这种实用程序应该容易地实施任何语言。

我想测试如何“友好”的语言是常规的“写入编译运行调试”循环,为匹配算法编写测试是多么容易,您可以在查找所需的API与文件一起使用的情况系统和基本I / O,编译器指出错误时有多么友好,如何“直观”是语言等。

我的样本大小相当谦虚 - 只是我自己。但是为了避免偏见,鼓励你自己做同样的(它不应该花太长)并比较结果。在用不同语言写作的实用程序之后 - 我问我的同行开发人员(〜20人)阅读并告诉它所做的事情,哪条线尚不清楚,读取和理解的是什么“更容易”。这些开发人员没有任何语言的经验,但是已经在其他语言中编码了很多,例如Java,C#,JavaScript,Kotlin,Swift等。

这里测试的语言是C ++,Go,Rust和Zig。我获得的结果是在Github.com/zserge/Glob-Grep上获得的,随时批评。

这一切都开始了,因为我想看看什么样的语言之曲。我从未使用过它,但听到了一些良好的反馈。没有以前的经验,我打开了Vim并开始编码。

完成该计划需要我〜1小时。通配符匹配算法(我以前知道,并且只有在Zig中只能实施)花了我〜20分钟。其余的正在寻找API来执行目录扫描和文件读取。

我喜欢的是什么:语言对C编码者令人惊讶的是直观。感觉非常简单,关于语言的文档(但不是STDLIB)非常清晰友好。

Vim Integation也非常好,对于一种年轻的语言(在我启用了Vim插件之前 - 我对格式化错误感到恼火,这是编译错误的错误)。

我喜欢错误处理方法。喜欢测试线束附带语言。甚至喜欢字符串只是字节数,就像在C.中一样

我对携带分配者周围的第一次反应是一个震惊,但实际上它甚至不明显。它给出了一种极简主义,即语言的核心如此简单,甚至没有使用动态内存。再次,非常接近C.

我不得不在写这篇文章时阅读很多Zig编译器和stdlib源,并且代码非常清晰简洁。

我不喜欢的是:stdlib文件是可怕的。我从目录扫描和文件I / O学到的一切 - 我从Github搜索结果中获得,这也是非常稀缺的。

编译器消息也远非友好,而是熟悉C的人并不是一项大问题。

在stdlib中缺少字符串处理例程是意外的,要使串行串一个人必须手动执行所有操作 - 分配缓冲区,将字符串放在那里。或使用格式化器和分配器以并排打印两个字符串并之后释放缓冲区。与S1 + S2仍然非常不同。

总的来说,核心语言很简单,我喜欢它,但STDLIB比LIBC更受限制。我希望这只是语言的早期时代的标志。

读取生成的Zig代码的人实际上提到了这是一个让他们实现程序所做的内容。这有点冗长,但明确,可预测和易于理解。并不令人惊讶,因为语言是以可读性的设计(没有隐藏的控制流,没有隐藏的分配,没有宏,没有运算符重载,没有成分谱图等)。

我有一些失败的尝试试图学习生锈。完成这个程序需要我超过2个小时,在完成后,我感到沮丧。

我喜欢什么:编译器消息很好。语言的文档也很好。但那可能是它。至少我这次没有终生错误的终身错误。语言周围的工具是现代而漂亮的。

我不喜欢的是:编译器消息太冗长并拍摄整个屏幕。不,我不想为每一个错误运行rustc - 索引。拜托,不要惩罚我。文档有时也太冗长了。我的意思是,它更好地拥有更多的文档,但首先拥有TLDR版本会更好。对于stdlib来说,具有简短的功能列表以及他们在一句话中所做的事情将更容易浏览作为读者。在明显的必要时,& str,str和[u8]明显,但为新人感到惊讶。

总的来说,在锈病中编码感觉像拼图解决我。可能很有趣和令人兴奋,特别是在用生锈作为爱好语言时,但对于大多数任务来说,我宁愿更喜欢“符合人体工程学”的语言,这是一个勉强明显的工具。

阅读所产生的生锈代码的人经​​常在过程中培养至少几个“WTF”问题。他们经常抱怨语法尚不清楚,需要注意细节。此外,模式匹配仍然是“主流”开发人员的不熟悉的事情。

这是作弊。我显然有一些以前的经历,但我想在这个实验中尝试。我花了〜15分钟来制作完整的“glob”实用程序,就像我预期的那样。

我喜欢的是什么:感觉非常富有成效,Docs对我的口味令人惊叹 - 简要介绍,但有用,可以立即打开相关的STDLIB函数来源并进一步调查。从过去的经验中,在编写应用程序时,我已经设想了如何使其多线程并提高性能(简单的粉丝)。

我不喜欢的是:太多的东西都在引擎盖下(缓冲I / O,GC)。你不觉得你控制着一切(如Zig)。太为自以为是 - 这是列表中唯一需要我创建3个单独文件以使其工作的语言。仍然可以使愚蠢的错误,如意外变色的阴影,或者在循环内使用Defer。

阅读结果的Go代码的人发现它清楚,有些人想知道内联的Walker函数(不必加内联,他们是对的)。有些人想知道多个分配,即a,b = c,d,它也不需要那里并使事情变得更加困惑。具有讽刺意味的是,如果我是新的去 - 我会写得更加简单的去代码。

虽然我有一些c体验,但我与现代c ++相比,我决定试一试。花了我〜20分钟完成,这是出乎意料的。

我喜欢的是什么:感觉熟悉,就像从过去遇到一位老朋友一样。我喜欢文档,有很多例子和良好的可读性。我惊讶地看到了现在的stdlib是多么强大。在文本编辑器和IDE中的支持也非常稳固。

我不喜欢的是:工具不好 - 没有建立系统,没有测试线束,没有兰特。我们习惯于过去,但这不是一种现代开发人员所期望的。太强大 - 对于这个非常任务C ++感到非常富有成效,但我可以想象在某些时候有许多不同的方法做某事并且所有人同样好(或坏),我可以想象自己在某些时候瘫痪。

读取生成的C ++代码的人实际上是过去读取的C或C ++,至少作为大学课程的一部分。许多人抱怨使用::,所以我猜我应该妥善使用命名空间。总的来说,因为在C ++代码中没有“品味” - 我相信它可能已经更清楚地写得很清楚,但我也看到了在没有甚至注意到的情况下如何写得多。

所有语言都产生了静态可执行文件,所有大小(2..5MB)都大致相同。最小的是Zig,最大的一个是生锈的。扫描整个/ usr / include文件树时,所有这些都具有大致相同的性能。这就是为什么我想强调技术特征通常与开发人员经历那么重要。

我想单独提一下建设时间。我跑了整个构建+测试+清洁循环一百次。去速度最快(如预期),另外三个是基于LLVM的,并且是〜3x-4x较慢。

这是什么意思呢?结果并不令人惊讶,往往遵循陈词滥调的语言:GO易于阅读,Rust复杂,C ++很熟悉,Zig看起来很有希望,但太年轻了,判断太小。

如果我必须编写一个不必与C代码交互的新服务/实用程序 - 我肯定会选择Go。如果我不得不打电话给一些c或c ++库 - 我会坚持c ++(不幸的是)。什么地方生锈和Zig在现代的编程世界中占据了什么 - 只有时间会告诉。我希望Zig在它变得过于利润之前获得更好的文档来获得人气。我肯定会仔细注意它,到目前为止,这是我遇到的第一个真实的替换,特别是在涉及到低级编码时。

但当然,C在这里仍然是它的年龄。仍有太多区域,其中c是唯一真正的选择。而且我很高兴C存在。

我希望你很喜欢这篇文章。您可以遵循 - 并贡献 - 在Github,Twitter或通过RSS订阅。