重温“千万字母表问题”看多范式编程语言改进

栏目: Ruby · 发布时间: 6年前

内容简介:重温“千万字母表问题”看多范式编程语言改进

去年 11 月写了一篇 《由“千万字母表问题”看多范式编程语言》 ,能够看到这些现代多范式语言的一些优势以及小的不足。而这些语言也在不断演进,时隔半年多我们再重温下相同问题,看看它们的改进成果。

原题目是瓜哥(@2gua)去年夏天在微博上出的一个题目:

【来做题】功能实现倒是很简单~ 用你熟悉的语言,统计一个字符串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 的波动更小、性能也更好一些。

本次测试仍采用运行多次取中位数的方式,数据如下:

语言 Ruby 2.4.1 Rust 1.17.0 Kotlin 1.1.2-2 Java 1.8.0_131 Julia 0.5.2 Swift 3.1.1
上次用的虚拟机 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')
}

与上一版的代码差异如下:

重温“千万字母表问题”看多范式编程语言改进

看到了什么?没错! groupingByeachCount ,正是上篇中所 期待的功能 !另外还有一小处改动是 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 支持 groupingByeachCount 以及数字字面值分隔符。

另外 Swift 4 也快正式发布了,期待它更好表现。Rust、Julia、Kotlin、Swift 这些语言都在快速发展中,相信未来会属于这些现代多范式语言,跟紧它们的步伐吧。


以上所述就是小编给大家介绍的《重温“千万字母表问题”看多范式编程语言改进》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

挑战编程

挑战编程

斯基纳 / 刘汝佳 / 2009-7 / 39.00元

《挑战编程:程序设计竞赛训练手册》分为14章,分别介绍在线评测系统的基本使用方法、数据结构、字符串、排序、算术与代数、组合数学、数论、回溯法、图遍历、图算法、动态规划、网格、几何,以及计算几何,并在附录中介绍了一些著名的程序设计竞赛以及相应的备赛建议与比赛技巧。每章的正文用十余页的篇幅覆盖了该领域最核心的概念和算法,然后给出八道可在线提交的完整编程挑战题目供读者练习。 全书内容紧凑、信息量大......一起来看看 《挑战编程》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码