【原创】关于Golang和Rust对比及语言的选择思考

    作为现在已经作为互联网企业高性能API标配的Go语言,以及在成长路上的Rust语言,都是互联网后端工程师重要选择的两个语言,也是很多人拿来做对比的两个语言,那么实际场景里应该如何选择呢。

    没有万能的语言(当然可以说C是万能的),只有适用某个时代或某个场景的语言。比如你用Python做高性能服务就挺麻烦的,用C语言做Web开发写CGI也是有点费劲的,或者拿Java做操作系统硬件驱动是不太合适的等等,都会有自己的适用场景。

## 编程语言主要干什么

    我们先关注编程语言干什么,基本定义是:编程语言(Programming Language)可以简单地理解为一种计算机和人都能识别的语言。一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动。

    里面提到编程语言两个最关键的事情:“数据” + “动作”,就是核心就是在某些“数据”上面进行对应的“动作”,映射成为编程来说就是“数据结构”+“算法(计算方法)”;数据结构中会涉及到数据的“存储”和“计算结构”,比如说存储在内存和存储在硬盘中的结构是不同的,比如你在内存中构建一个B+树是可以的,但是没有必要,这种结构更适合在硬盘里使用。

    对于编程语言来说,我们是比较关心数据的存储和计算方法的,数据只能存储在内存和硬盘中,实际大部分计算过程我们都是在内存中完成的,那么针对内存的使用和管理就尤为重要了,这也是很多编程语言需要关注的问题。

这里我们就出现了关于编程语言针对内存的管理动作了,实际上大部分编程语言本质都是:“语法 + 内存管理 + 与操作系统交互 + 语言特性 + 内置基础库”,这几部分工作,大部分都是需要编程语言的编译器或者是Runtime(VM)来解决的,这些解决方法,也就决定了语言的使用简单还是复杂,以及对应适用的场景。

## 编程语言对内存管理不同形成的分类

    上面我们提到了,针对“内存”的管理和调度使用,是编程语言很多特点区分的重要分界点,那么我们就需要看看目前主流的编程语言都是如何管理使用内存的:

现在主流编程语言内存管理模式分类:

1. 不关心数据类型 - 脚本语言动态内存管理GC

主要代表是 PHP、Python、JavaScript 等等,采用引用计数或个别的标记清除等gc机制,无法管控gc过程,但是语言操作简单;

2. 关心数据类型 - 静态语言(关心数据类型)动态gc管理

主要代表是 Go、Java、C# 等等,主要采用引用计数(ref-count)+标记清除(mark/sweep)方法,标记清除大致都是类似于“三色标记”或“新生代/老年代/持久代”等等,标记清除都会多少存在STW问题,另外无法暴露内存管理方式给调用;

3. 关心数据类型 - 静态语言自主内存管理

主要代表是 C、C++等等,主要是编译器提供基本的内存分配释放接口联动操作系统,需要开发者自主调用API管理内存,如果不管理会存在内存泄露问题。

4. 关心数据类型 - 静态语言动态内存管理-升级版

主要代表是 Rust 等,主要不是通过gc的方式进行内存回收,直接在编译器和执行层面通过“所有权”判断直接把不用的变量进行回收失效,效率高并且不会存在STW的问题,内存管理的性能比 Go/Java 等动态gc的策略性能更高。

其实我们通过上面的几个分类,明显能够发现几个时代变化带来的一些区别:

    比如说Java和C#基本都是纯工作在VM中的,并且VM是以为一种运行容器方式存在的,无论是 JVM还是.Net Runtime 都是一种容器,但是Go的先进性是代用了Runtime和应用代码共存逻辑,通过g0协程等等思路来调度处理内存管理协程等等,明显设计要更先进一些,更接近于类似于C/C++这种纯静态语言,有点介于在C/C++ 和 Java 之间的设计思路。

    Rust走了完全不同一条路,在内存管理上面另辟蹊径,在学习了C++和D语言以及函数式编程语言基础上,走了一条新路,就是让内存可以直接不依赖于Java/Go这种gc机制达到回收目的,直接通过变量“所有权”的方式直接进行失效回收,减少了可能会STW的可能性,性能大幅提高,又减轻程序员手动释放内存的负担。

## 一些编程语言选型的个人建议结论

其实通过上面的基本介绍,其实大致了解了一个语言底层运行逻辑,大概就知道了这些编程语言选型建议:

  • 快节奏验证业务和数据算法能用性,直接使用 脚本动态语言是最方便的,比如Python和PHP,互相在不同场景,比如适合数据计算和Web开发等区别;

  • 高性能稳定线上服务优先考虑静态语言动态gc语言,具备脚本语言的内存管理不关心性,又具备静态语言稳定性,比如 Go和Java,但是Go对比Java语法更干净简洁,更未来;

  • 对于需要精细化内存管理,对稳定性,系统底层要求高的,可以采用纯静态语言,比如 C++和Rust,但是Rust对比C++更先进;

初步从目前这些情况来看,做一些简单的建议:

  • Go良好的适合取代Java的场景,因为设计思路比较像,但是Go更先进,生态未来更强大,并且语法简单,在云原生和分布式多核时代绽放光彩。

  • Rust良好的适合取代C++的场景,因为设计思路像,但是Rust更先进,让程序更舒服的能够开发像C++一样高性能的程序。

## 最后

纸上得来终觉浅,绝知此事要躬行。

Go也好,Rust也好,优劣好坏只有自己试试才知道,然后看看是否适合自己的业务场景或者个人的喜好。

希望本文对您有所帮助。


## 延伸阅读

如果你是一个Go程序员,如果想在Go语言中像C/C++或者Rust一样管理内存,可以了解一下XMM库:

XMM是一个类TcMalloc的内存管理器,通过6000行纯Go代码构建,可以在Golang中让你像 C/C++ 一样的操作操作系统内存,并且协程安全,完美逃逸Go的gc机制,让你的程序性能杠杠的,摆脱 sync.Pool 或者 []byte 流操作的痛苦,构建高性能程序必备!

开源地址:(欢迎关注点点star,提提pr~)
https://github.com/heiyeluren/xmm


欢迎关注“黑夜路人”公众号,获取最新技术文章:

猜你喜欢

转载自blog.csdn.net/heiyeshuwu/article/details/123133475