另一种计算机语言比较

作者:迈克尔·斯科特博士

在本文中,我们描述了在多种计算机语言中实现高性能密码库的经验

大多数人都有喜欢的语言来编程。或者,他们可能会选择两到三门课程。 也许他们喜欢一种语言来编写高级脚本,而另一种语言来编写低级脚本。 我一直以来都喜欢C和C ++,并且有多年使用它们的经验。 过去,我对比赛没有任何评论,因为我对比赛没有经验。 我本来会看不起的一些人-Java是为无法直达指针的人而开发的,Rust是为高falutin学术类型提供服务的人。 实际上,我本来会发生各种荒谬的偏见,但是所有这些都是基于没有任何实际经验的。

作为一个内部项目的结果,我的任务是以尽可能多的语言实现一种便携式高性能密码语言。 所有语言的所有实现都应为相同的输入提供完全相同的输出。 该库本身很有趣并且很有用,并且在此站点的其他地方都有记录。 只需说它就实现了对称加密,散列,随机数生成,公钥加密(使用RSA和椭圆曲线)以及基于配对的加密即可。 最后一个是椭圆曲线密码学的产物,这对我的雇主特别有用。 该库执行许多非常复杂的全整数计算。 也许最复杂的计算是“配对”本身。 实际上,基于配对的加密技术的可行性取决于快速计算配对的能力。 因此,性能是一个大问题。

除了向Kernighan和Richie致以崇高的敬意以及他们对C的致敬之外,很难不想到过去40年来的语言发展。这里考虑的所有语言(C,Java,Swift,Javascript,Rust,C#和Go)都非常像C。 实际上,C与它的直接前身Fortran之间的区别要比C与此处考虑的任何新语言之间的区别更大。

数论密码学所需的整数算术类型相当特殊。 由于密码学中使用的数字(可能为256位)往往比寄存器大小(可能为64位)大得多,因此我们需要实现所谓的多精度算术。 因此,理想情况下,这些大密码数字之一应表示为计算机字阵列。 显然,处理器的字长越大越好,因为256位数字可以更有效地表示和操纵为4个64位“数字”,而不是8个32位数字。

现在,当两个32位数字相乘时,结果是64位。 Kernighan和Richie清楚地理解了这一点,他们具有预见性来指定两个整数类型,即int和long。 两个整数的乘积将适合一个long。

因此,在32位处理器上,我们需要64位类型。 在64位处理器上,我们需要128位类型。 这就是麻烦的开始。 令人难以置信的是,即使64位处理器现在无处不在,我们的“现代”计算机语言也都不支持标准的128位整数类型,现在甚至将32位处理器推向了我们在移动市场上的利基市场。 幸运的是,负责流行的C和C ++的GCC编译器的负责人已经看到了曙光,现在有128位类型可用。 GCC定义了自己的标准。

这意味着在C语言中,通过明智地使用#define和typedef,我们可以立即从32位版本的库切换到64位版本的库。 ,这在任何其他较新的语言中都是不可能的。 Java是一个很好的例子,其中int类型始终卡在32位,而long类型卡在64位。 在32位处理器风靡一时的今天,如今已发展成球形。 通过伪造128位伪类型,我们可以效率低下地解决问题。 但是它会很慢。 因此,看来我最初对C的偏见将有一定的道理。

我需要做的一件事是一个文本编辑器,它可以应付所有语言,并且可以完成诸如关键字突出显示之类的出色工作。 我认为没有人能够支持所有人,但确实如此。 让我们来欣赏Sublime Text!

强烈建议-在这里https://www.sublimetext.com/获取。

当我用每种语言编程时,斯德哥尔摩综合症迅速发作。 我实际上开始喜欢他们,并开始看到他们的个人优势。 对C的某些更改似乎相当武断。 半冒号(Java,Javascript,C#)进入(Swift和Go),而当我习惯于没有分号时,它们又回到了(Rust)。 那么旧的for(i = 10; i> = 0; i —)语句有什么问题? 它是如此富有表现力,您几乎可以用它做任何事。 Java,C#,Javascript和Go一致,但Swift和Rust不一致。 在(0..11).rev()中,我有什么好处呢? 此外,每种语言都有自己的变量命名惯例,并且(像Rust)可以非常乏味地坚持我们遵守内部规则。

对我来说,一个大问题是内存管理。 并不是说我有很多内存要管理,实际上却很少。 因此,我希望所有内存都从堆栈而不是堆中分配。 使用C,您可以确切知道它的来源。 作为程序员,我有点控制狂,所以我不知道其他语言在幕后到底是怎么回事而感到不安。 似乎Java和Go和Swift(在较小程度上)喜欢使用堆内存,而Rust在这方面更像C。 对于我不完全适应的新语言,有一种“留给我的态度”。

我喜欢简洁的语法,Swift,Javascript,Java和Go在这方面趋于友好。 Rust更像C,并且很难避免&s和muts过多。 给出相同的结果,我希望每种语言都经过精心设计,以使最简洁的语法能够导致最快的代码。 换句话说,我不想为了使它高效地执行某项任务而奋斗。

我在Rust方面遇到的麻烦最多,但后来发现了一些问题。 使用Rust,我的调试趋向于从运行时调试转到编译时调试。 Rust编译器实际上使编写不正确的代码变得困难。 实际上令人印象深刻。

Go真的很聪明。 我喜欢它的极简主义。 我喜欢它的“增强结构”,它非常适合我尝试做的事情。 Rust有类似的东西。 我实际上并不需要类的全部功能,而其他一些语言则强加于我。

我遵循的顺序是C到Java到C#到Javascript到Swift到Rust。 这可能是相当偶然的,因为与前任的差异很小。 实际上,从Java到C#的过渡是如此简单,我有一个自动工具可以帮我实现。
对于Swift来说,成熟度是个问题,因为即使在我撰写本文时,规范也在不断变化。 希望它将在版本3中解决。

4.1。 多快?

我的配对计算程序由一个循环组成,该循环计算了1000个配对。 对于那些了解配对的人,实际配对是在455位BLS曲线上计算的。 在所有情况下,编译器优化都可以最大化。

所有计时都以秒为单位,主要是在i3 Core Intel处理器上。 Swift计时位于Apple Mac上,已缩放以进行比较

1. C(32位)— 22
2. C(64位)— 9
3. Java(32位)— 41
4. Java(伪64位)— 24
5. C#(伪64位)— 21
6. Javascript(Google Chrome)-390
7. Go(伪64位)— 182
8. Swift(32位)— 187
9. Rust(32位)— 23

4.2。 讨论区

Go到底出了什么问题? 太慢了! 好的,它编译速度非常快,但是谁在乎。 它就像拥有无限下载量的ISP,而没有提到非常有限的带宽。 和斯威夫特不是那么快。 但是您必须佩服Java和C#即时编译器的性能。 显然,这些投入的人年已获得回报。 Rust声称速度很快,而且确实如此。

但是就性能而言,C仍然是赢家。 我最喜欢哪一个? 好吧,每个人依次使用它,而我最后的努力是在Rust上,所以是的,现在我非常喜欢Rust。 但是在冷静期过后,我可能会整整回到C。

在另一种计算机语言比较中下载本文


本文首次发表于 2016年8月3日 MIRACL 网站 的博客部分