前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang对比C++的开发环境的变化

Golang对比C++的开发环境的变化

原创
作者头像
mariolu
发布2021-03-29 23:53:06
2.6K0
发布2021-03-29 23:53:06
举报

前言

这篇文章描述工作观察到的开发现状中存在的问题, 因为目前业务后台开发语言绝大多数都是C++, 并针对现状, 试图给出一个在 Golang 的开发生态 下的一些解决方案。

一、问题和对比

1.1 语言本身的开发效率

开发效率本身涉及的东西方方面都有, 在这里, 单纯从语言出发, 说一下开发效率高低影响的因素

1.1.1 内置语法与功能

C++ 的语法给人的感觉就是矛盾的, 这个语言 从语言本身语法非常丰富, 比如支持模板的一个特性, 有模板, 模板特化, 偏特化, 全特化, 实例化的 "参数匹配" 这些概念需要用户学习, 但是 自身却连一个字符串分割的内置实现都没有

Golang 与之相反, 自身的语法并不多, 甚至不多到了 匮乏 的程度(比如重载都没有), 但是内置的库函数却非常丰富, 字符串, 时间, 网络, 协程, 管道, 字典, 数组, json等等, 基本常用的功能都有, 这导致对于 90% 以上的业务代码, 用语言自身的代码就能完成

这带来的一个结果就是, 仅从常见的业务功能来看, 同样的逻辑实现, Golang 需要的代码量, 包括行数和标记符的数量, 比 C++ 都要少一些, 代码量少通常意味着好阅读, 好理解, 好维护

内置功能全面的另一个结果就是, 不同的人实现同样的逻辑, 代码容易写得一致, 代码一致就不容易有 外部依赖库选择 的问题

1.1.2 外部依赖库

由于 C++ 内置功能非常缺乏, 而每次都自己实现常见的功能非常耗费时间, 所以就出现了各种各样的功能丰富的扩展库, 以及各种各样的用户自己实现的 tools 目录库

问题出在 各种各样 上, 这导致不同的人实现的业务代码, 因为库的不同, 在表现形式上会有各式各样的差异, 为了减少这种差异, 除了语言本身之外, 还需要定义一些依赖相关的规范, 来让代码变得一致

比如库 boost, 但是 boost 也有自己的版本, 不同的版本 api 不完全一致, 这导致了用户的学习成本变得更高, 语言 + 特定版本的库, 在我们的环境里, 在写任意的业务代码之前, 用户就需要了解这些

而 对于 Golang, 这些问题相对就少一些, 用到依赖库的时候, 往往是和外部环境, 比如数据库, 特定的协议等等组件打交道的时候, 用户知道自己要做什么, 要了解什么, 而这个外部依赖的范围, 往往也集中在所需要进行业务开发的范畴内部, 因此, 对于 Golang, 不会出现 boost 这种东西

用户的学习成本也低一些, 拿来就用

1.1.3 语言高级特性

相比 C++, Golang 几乎可以将所有精力放在业务上, 而不用担心语言自身存在的问题, 比如栈溢出的问题

同时, 为方便工程应用, Golang 将后台开发所需要的特性做了很好的接口封装, 协程开发, 一个 go 关键字就能启动一个新的协程, 协程通信用内置管道, 无锁高效, 看下面的一个并发编程的示例, 并发请求多个 uri 地址, 先返回的打印出来, 并且带 3s 超时, 26行代码(带空行)

1.2、构建和编译

C++ 的编译并不好做, 编译工具很多, make, cmake, 以及衍生的 automake, autogen.sh, configure.sh, 让事情变得复杂

C++ 使用 include 来指定头文件, 编译时使用额外参数指定库文件, 使用文件作为依赖, 就会出现依赖 不对 的情况, 这个不对可能是 .h 和 库文件分离导致的可能的不一致, 可能是库文件版本比较多, 以及操作系统的差异带来的 core 和无法运行, 为了防止重复引入, 还有一些 ifdefine 宏, pragma once 这些语法

而且, 以本地文件为依赖, 也会出现文件重复的情况, 重复 + 自定义需求, 就会导致文件的不一致, 这也是我们的文件里, 不同项目之间大量代码重复的原因之一

Golang (除了 cgo 以外), 做了代码和库文件的统一, 引入以 而不是文件的形式进行, 事实上, 在 Golang 中, 文件是一个非常非常没有存在感的东西

以 包 为单位进行引入, 而且支持直接引入代码仓库路径, 使得 Golang 的代码复用相对容易一些, 不会因为不方便编译的原因, 自己下载库修改完, 不 merge 造成不一致, 同时, 以 包 为隔离, 也容易使得代码的模块划分相对好做, 这些特性, 使得 Golang 的 Makefile 很好写, 基本就是一行代码搞定

在依赖管理上, go mod 的工具包已经可以稳定使用, 在代码库里 import 包, 会有相应的工具帮你自动生成依赖包和版本文件, 一般不需要手动管理, 在编译的时候, 包会自动下载(而且看不见下载的包在哪, 对用户来说, 不感知编译过程)

另一方面, Golang 编译的文件基本不需要依赖库, 基本是一个二进制就能跑, 部署方便, 而且, 即使在 Linux 上, 也可以编译跑在 Windows, Android, Mac 以及各种操作系统运行的二进制, 非常方便

在编译速度, 我们的 C++ 框架编译现状不太好, 编译速度很慢, 环境要求也不低, 修改一行代码, 需要编译很久才能测试效果, 而没有框架的包袱, Golang 的编译速度是秒级起

产出物大小上, 由于框架比较复杂, 一个 hello world 代码的二进制编译在 100M 以上, Golang 的 hello world 在 10M 以下

在构建编译方面, Golang 比 C++ 的领先, 有 级别的差异

1.3 工具链

Golang 在工程实践上做得比较完善, 从代码编辑, 格式化, 跳转定义, 重命名, 编译, 调试, 到构建工具, 甚至到文档生成, 测试, 代码风格都做了定义, 并给了相应的工具进行实战

就用代码定义来说, godef 提供了非常好的跳转, 在内置包, 三方包之间, 都可以很方便地跳转, 与 C++ 要事先生成 ctags 文件并需要手动更新相比, 要好用得多

Golang 提供的工具链, 足以应对一般的业务开发场景

1.3 反射机制

在 Golang 里, 基于反射, C++ 没有反射, 1 的部分需要借助代码生成来解决, 其他几点, 由于开发效率的问题, 实现上相对耗时会久一些

1.4 可持续性

这里指的是随着时间的推进, 在新的成员加入后, 对之前的工作的延续程度

拿 C++ 举例, 即使是今天, 在编写一些通用库的时候, 这边还不得不以 C++98 的语法进行编写, 否则, 由于一些不可知的原因, 会碰到一些不可知的问题

而 Golang 相对年轻, 且在 1.x 的多个版本迭代中, 并未出现语法上不兼容的情况, 而语法兼容也是 Golang 发展的一个考虑因素, 即使现在在草案中的 Go2, 也没有考虑要使得 1 下的代码无法编译运行

以年为维度的时间来看, 我们推广 Golang 的成本, 甚至会小于推广 C++ 11, 14, 17, 20的成本

二、Golang 的对比劣势

2.1 重载

Golang 原生不支持重载, 而重载已经是一个应用广泛的编程实践之一, 为了在 Golang 中实现重载的功能, 开发者往往使用不定参数 + 反射, 这给代码的可读性和性能带来了损失, 同时, 也丧失了重载灵活 + 类型安全兼顾的优点

在重载使用较多的场合, 使用 Golang 会增加代码量

2.2 性能

在一些常规的语言级别的性能中, Golang 被认为无法与 C++ 相比, 在极限场景下, 会有倍数级别的性能差异

为了弥补这种差异, 对于性能要求比较高的应用, 在半数以上的时间, 开发者往往需要和运行时进行比较深入的沟通, 才能得到过得去的结果

而且, 现在有一种观点, 认为 GC(垃圾回收) 是一种失败的设计, 无 GC 也无手动分配内存的语言, 比如 Rust, 在学术上的评价更高

在未来, 是否有 GC 的语言都会因为这种原因被淘汰掉, 不是一件不可能的事情

2.3 成本

包括我们的人才构成, 招聘策略, 培养与转移成本, 适配一个适合我们场景的 rpc, 两语言的并存带来的额外的成本等等, 都是要仔细考虑的事情

而将这些工作变得平滑, 阵痛少, 需要精力

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、问题和对比
    • 1.1 语言本身的开发效率
      • 1.1.1 内置语法与功能
      • 1.1.2 外部依赖库
      • 1.1.3 语言高级特性
    • 1.2、构建和编译
      • 1.3 工具链
        • 1.3 反射机制
          • 1.4 可持续性
          • 二、Golang 的对比劣势
            • 2.1 重载
              • 2.2 性能
                • 2.3 成本
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档