去年 11 月写了一篇《由“千万字母表问题”看多范式编程语言》,能够看到这些现代多范式语言的一些优势以及小的不足。而这些语言也在不断演进,时隔半年多我们再重温下相同问题,看看它们的改进成果。
【来做题】功能实现倒是很简单~ 用你熟悉的语言,统计一个字符串abcdefghijklmnopqrstuvwxyz…abcdefghijklmnopqrstuvwxyz(1千万个a-z,不可直接a=1千万……) 中每个字母的个数,最后输出类似图示。要求除了更好的方式(如更加Pythonic的方式),还要计算越快越好,并打印出代码执行时间(打印效果类似图示)
上次以 Ruby 版为基准,对比了 Rust、Kotlin、Julia 与 Java 8 版的代码与速度。这次在上次的基础上增加了 Swift 语言版,并将所有语言都升级到了最新稳定版。 测试环境使用与上次相同的虚拟机(4 核 4G、操作系统为 Ubuntu 14 x64),另外追加了 AWS 新加坡区的 EC2 测试环境,配置是 c4.xlarge(4 核 7.5G)、操作系统为 Ubuntu 16 x64,AWS EC2 的波动更小、性能也更好一些。
本次测试仍采用运行多次取中位数的方式,数据如下:
上次用的虚拟机 | 7.586s |
3.072s |
3.611s |
5.981s |
10.363s |
22.133s |
AWS c4.xlarge | 1.142s |
2.559s |
3.018s |
5.148s |
9.013s |
17.515s |
这次依然用 Ruby 版代码作为基准,是因为它的速度相当快,代码相对于上次无调整,参见上篇。各语言新版本在速度上都有明显提升。
Julia
从上面速度数据看,Julia 版代码还是比较慢,但这次不是垫底,并且相对于上次的速度提升非常显著,其代码依然是最简洁的:
function f()
s = repeat(join('a':'z'), 1000_0000)
Dict(c=>count(i->i==c, s) for c in 'a':'z')
end
@time print(f())
与上一版代码相比,构造字典的列表推导语法变了,需要用 Dict()
显式构造字典,否则会出现警告。其代码差异见下图:
上篇中提到了对于 Julia 的关键是性能改善。目前看来它的进步非常大,就这两次评估而言,性能上有数量级的提升,其速度提升超过 10 倍。
Rust
Rust 版代码变化很大。上篇中提到为了实现对数级重复写了不少冤枉代码,现在不用了,因为 Rust 在 1.16 起(这次用的是 1.17)标准库就自带字符串重复了,这一版用的代码如下:
// 编译方式 rustc -C opt-level=3 z1.rs
use std::time::SystemTime;
fn main() {
let now = SystemTime::now();
let letters: String = (b'a'..b'z'+1).map(|c| c as char).collect();
let repeated = letters.repeat(1000_0000);
for b in letters.as_bytes() {
print!("{}: {}, ", *b as char, repeated.as_bytes().iter().filter(|&x| x==b).count());
}
let elapsed = now.elapsed().unwrap();
println!("\ntime: {}.{:09}s", elapsed.as_secs(), elapsed.subsec_nanos());
}
与上一版的代码差异如下:
如图所示,新版 Rust 对高效字符串重复的支持,让新版代码相对于旧版省去了一大段自写代码。另外本次测试比上次快了很多,说明 Rust 新版在性能上也已提升不少。
Java 8
Java 版代码无变化,新的 Java 稳定版没有本质改动。但由于其他语言的进步,上次最快的代码如今在速度上已经平淡无奇了。
Kotlin
在上篇中提到 Kotlin 因为缺少 groupingBy()
与 counting()
这样的 Collector,所以性能不及 Java 8。新版的性能提升上来了,让我们看看新版的代码吧:
import kotlin.system.measureTimeMillis
fun main(args : Array<String>) {
print(measureTimeMillis {
val letters = ('a'..'z').joinToString(separator="")
val repeated = letters.repeat(1000_0000)
println(repeated.groupingBy { it }.eachCount())
} / 1000.0)
println('s')
}
与上一版的代码差异如下:
看到了什么?没错!groupingBy
与 eachCount
,正是上篇中所期待的功能!另外还有一小处改动是 Kotlin 现在也支持数字字面值分隔符了。 现在 Kotlin 有了与 Java 8 同样自然的方式,代码还简洁很多倍,替代 Java 的潜质更加明显了。如今 Kotlin 已经成为 Android 的官方开发语言,其发展势头越来越好。
Swift
这次还引入了同为现代多范式语言的 Swift,最近《Swift is like Kotlin》被大家疯狂转载,两门语言确实很像,就本篇讨论问题来看简洁性虽不及 Kotlin 却也还不错。而这次测试中它的速度垫底倒是没想到的。
// 编译方式 swiftc -O y1.swift
import Foundation
let date = Date()
let letters = (0..<26).map({String(UnicodeScalar(UnicodeScalar("a").value + $0)!)}).joined()
let repeated = String(repeating: letters, count: 1000_0000)
for c in letters.utf8 {
print(Character(UnicodeScalar(c)), repeated.utf8.filter{$0 == c}.count, separator:": ", terminator:", ")
}
let elapseTimeInSeconds = Date().timeIntervalSince(date as Date)
print()
print(elapseTimeInSeconds)
上面的 Swift 版代码的看起来与 Rust 版更接近一些,这并不奇怪,因为这两门语言在发展过程中存在不少相互借鉴之处,另外还可以回顾下年初 Swift 之父去特斯拉、Rust 创始人加入 Swift 的消息。
从上面代码和本次测试来看,Swift 的性能及其字符处理的简洁性方面都还有提升的空间。
小结
这一版测试结果非常令人欣慰,甚至可以说惊喜。Rust、Julia、Kotlin 在性能上均有提升,而且都达到了我在写上篇时的期望,分别是:
- Julia 的性能提升了一个数量级。
- Rust 支持高效字符串重复。
- Kotlin 支持
groupingBy
与eachCount
以及数字字面值分隔符。
另外 Swift 4 也快正式发布了,期待它更好表现。Rust、Julia、Kotlin、Swift 这些语言都在快速发展中,相信未来会属于这些现代多范式语言,跟紧它们的步伐吧。
相关推荐
学习LOGO语言不仅可以提升编程技能,还能培养问题解决能力、逻辑思维和抽象思考能力。它鼓励试错和实验,使得学习过程充满乐趣。无论你是初次接触编程,还是想重温基础,这个LOGO语言安装包都能提供一个理想的起点。...
《F-Basic语言与编程技巧》是一本专为任天堂NES(Nintendo Entertainment System)学习卡设计的编程指南,深入探讨了F-BASIC语言的应用和高级技术。这本书旨在帮助读者掌握在8位游戏机时代如何利用F-BASIC进行游戏...
近年来随着数据科学的出现,Python 的重要性成倍增加,它已成为数据科学和开发的主要编程语言,具有独特、灵活、语法非常简单并且拥有强大的社区等特点。一些全球知名的应用程序如 BitTorrent、DropBox 和 YouTube ...
LOGO语言,全称为“Logo”,是一种以图形编程为主的教育性编程语言,旨在帮助初学者理解计算机编程的基本概念。...无论你是编程新手还是希望重温经典编程语言的老手,这个版本的LOGO语言都值得你一试。
JavaScript编程语言以其跨平台、动态特性和广泛的浏览器支持,已经成为构建各种类型应用程序的强大工具,包括模拟器。模拟器是能够模仿其他硬件或软件系统的行为的程序,使得用户可以在不拥有原生环境的情况下运行...
标题中的“可以用来怀旧的开发语言包01”指的是这个压缩包可能包含了若干个早期的编程语言开发环境,让熟悉这些技术的老程序员们能够重温旧日时光。描述中的信息暗示了我们可能会找到Turbo C、Pascal以及Prolog等...
齐民友所著的《重温微积分》是一本旨在引导学生深入理解微积分,并启发他们探索现代数学领域的书籍。书中不仅回顾了微积分的发展历史,还涉及了数学与物理学之间的内在联系,以及现代数学的发展和应用。作者认为,...
在"编程语言和环境"课程中,重制这款经典游戏不仅能让学生重温游戏的乐趣,还能让他们深入学习JavaScript编程语言和相关开发环境。 首先,我们来看看"lode-runner"项目的核心——JavaScript。JavaScript是一种广泛...
总的来说,这个寻宝游戏项目涵盖了基础的编程概念,为初学者提供了一个有趣的实践平台,同时对有经验的开发者来说,也是一个重温基础知识和提升编程技巧的好机会。通过深入研究源代码,我们可以更深入地理解编程语言...
无论是想要了解新的编程语言特性,还是重温已学过的概念,ChatGPT都能提供实时、互动的学习体验。它可以根据你的需求提供定制化的学习路径,让你在短时间内提升编程技能。 在团队协作中,ChatGPT也可以发挥重要作用...
重温微积分 - 齐民友
综上所述,"经典的飞机大战 儿时的回忆 python编程"是一个利用Python编程语言和pygame库来重温经典游戏的项目。通过这个项目,开发者不仅可以提升Python编程技能,还能深入了解游戏开发的基本流程和技巧。
在描述中,多次提到了“tc 计算机语言编程软件常用软件\软件源\TC.rar”,这可能是指该压缩包包含了一些与Turbo C相关的常用软件资源或源代码。"软件源"暗示了可能有编写的源代码文件,这些文件可能是示例程序或者...
通过习题,可以实践多线程编程,解决并发问题。 7. **反射**:掌握Java反射机制,能够动态地获取类的信息并调用其方法,这在插件开发、框架设计等方面有广泛应用。 8. **枚举与注解**:了解枚举类型和注解的使用,...
《Visual C++ 6.0 编程实例与技巧》这本书是针对初学者和有一定基础的程序员设计的,旨在深入浅出地介绍如何利用Visual C++ 6.0这一...无论你是编程新手还是希望重温经典的老手,都能从这本书中收获宝贵的经验和知识。
"超想tc3.0编程系统"是一款专为中文用户设计的编程环境,它提供了全面的编程工具和服务,旨在帮助用户高效地进行程序开发。TC3.0是Turbo C++ 3.0的简称,这是一款经典的C++集成开发环境(IDE),由Borland公司开发,...
【VC05编程软件】,全称为Visual C++ 2005,是微软公司推出的一款集成开发环境(IDE),主要用于C++编程语言的开发。这个版本是C++的一个里程碑,因为它引入了许多新特性和改进,对开发者来说具有重要的意义。 在...
12. **实际案例分析**:书中可能会包含多个实际项目案例,如数据库管理系统、图形图像处理工具、网络聊天程序等,通过这些实例来加深对Delphi编程的理解和应用。 通过阅读《DELPHI 5编程实例与技巧》,你可以系统地...
《重温微积分》可能会回顾微积分在物理学中的应用,如牛顿第二定律F=ma中的力与加速度关系,或是利用微积分求解动力学问题,如摆动周期、抛体运动等。此外,书中可能还会探讨微积分在几何学中的应用,如曲线的弧长、...
《Visual Basic 6.0应用编程150例》是一本深入浅出的教程,旨在帮助初学者和有一定基础的开发者掌握Visual Basic 6.0这一经典编程语言。Visual Basic 6.0(简称VB6)是微软公司推出的一款可视化的、面向对象的编程...