我写了一些歌,感觉很棒

我写了一些歌,感觉很棒

原文:https://medium.com/hackernoon/i-wrote-some-golang-and-it-felt-great-3c3367a67db5

我作为 Node.js & React 开发人员编写 Golang 的经历

免责声明:我写这篇文章是因为我刚开始学习 Golang,所以任何关于 Golang 的评论都存在明显的知识空白。

我一直在考虑让学习围棋——我的主要堆栈是 Node.js 和 React,我一直在寻找一种更高性能、专注于并发的语言来做一些改变,因为 Node 并不总是答案。这篇文章是一个小文档,记录了我最终是如何尝试这门语言的,以及为什么我真的喜欢它。

背景

不久前,我有了一个想法,需要一个基于英语词典内容的经过处理的数据集合,用于一个附带项目,只是我不想要数据库,我想要一个可以存储在内存中的文件,因为成本原因,我不必托管它。它将是一个 express 应用程序的基础,我将用一个简单的 React 前端来显示它,所以我想编写脚本来在 Node 中构建数据文件;一部分是因为我对它很了解,一部分是因为它很适合 JSON 和松散嵌套的数据结构,还有一部分是因为它上手很快。

在几个小时的 npm 安装、承诺包装和一些数字运算之后,我设置了我的脚本来运行,并在它运行时做了一些控制台日志记录来跟踪进度(提示:如果你想尽可能地从节点中挤出所有性能,就不要console.log()),希望它能在一夜之间完成。

没有。

它到了字母 P 处,减速停下。但是为什么呢..?在我写这个剧本之前,我算错了一些事情。首先是文件大小;我的数据集是基于 129,000 个单词。每个单词都有一个嵌套对象,其中包含一组值和分数——所以我在内存中存储了 129,000 个深度嵌套的对象。

您知道 V8 编译器在默认情况下对 32 位系统的最大内存限制是 512MB,而对 64 位系统只有 1GB 吗?您可以将其提升至约 1.7GB,但仅此而已。所以我的巨大内存对象的内存快用完了。

狗屎。不理想。我的解决方案?

小溪!如果我将数据传输到 JSON 文件,这样我就不用担心内存中的数据了,会怎么样?完美。所以我在几个小时内重构了我的代码,并让它流到我的文件中。内存使用下降,它嘎吱嘎吱地前进,所以我再次离开它一夜。当我醒来时,一切都结束了;太好了!不太好。我新创建的 JSON 文件是 4.2GB。考虑到节点内存的限制,它不完全可用,实际上也不可能。不管用什么语言,我都不建议加载 4.2GB 的文件。

那我该怎么办?我需要这些数据被一个 API 访问和输出。如果我即时计算我需要的值会怎么样?我没有幻想这个副业项目会爆炸,需要处理大量的流量,所以我认为这很好。因此,我再次着手重构代码,并将其直接集成到我的 API 中。问题三?速度。

在 Node.js 中实时计算一个我需要的值大约需要500 毫秒,这是一个问题,因为我需要为我的最终产品的每个请求多次点击这个 API。等待 5 秒的结果根本不是一个选项(好吧,它是,但让我们假设人们会使用它,并需要它很快)。

为什么这么慢?请记住 Node.js 不是多线程的(尽管人们喜欢假装它是),它的并发模型基于事件循环,这允许它执行非阻塞 I/O 操作。它通过将操作交给系统内核(通常是多线程的)来完成,系统内核可以在后台处理进程,直到它准备好将结果返回给节点。

因此,我需要一些多线程的、高性能的、有趣的东西。我过去做过一些 JavaC++C#PHP ,但我认为这是一个尝试不同事物的好机会——我考虑过使用 ScalaErlangelixin的功能方面,但我也想要结果,不想陷入我仅有的范式中

虽然我确实想学一门函数式语言,有什么建议吗?

因此,在得到一位同事的称赞后,我选择了 Golang 我做了一些在线参观(不耐烦),并花了一些时间来适应——再次定义类型(我还没有尝试过 Flow)是我不习惯做的事情。不管怎样,在几个小时内,我就有了重新创建实时数据查找所需的基础知识。

那我是怎么找到的呢?

让我们从速度开始。我的库实时查找平均需要 8ms 来获取我需要的值。这是 6250%的性能提升。可笑!

我肯定能以这样的速度工作。

我喜欢的其他运动

标准程序库

Golang 标准库非常详细,到目前为止已经包含了我创建 2 个项目所需的所有功能。文档很详细,包含示例,很容易遍历,除此之外,不需要npm install **everything**真的让人耳目一新。

所有代码看起来都一样

Go 语言规范是 tiny (认真对比一下 Java 的)。结果是,学习这种语言的能力只需要很少的时间(相对而言),就可以让你开始真正的编程。做每件事没有 50 种方法,通常只有 1 或 2 种,这意味着即使你是这门语言的新手,阅读别人的代码也不会被难住。

Go 的依赖管理基于严格的文件结构,这也意味着一切都在你期望的地方,你不必在文件夹结构中寻找你要导入的东西,这是显而易见的。

G ofmt 是另一颗宝石,它让编写风格相似的代码成为一场梦;一个内置的命令可以格式化你的代码(它甚至可以为你简化)。

不再是❤.了

并发性很容易推理

Go 使用 goroutines 和通道处理并发;生成并发函数的简单方法和分别接收它们的结果的方法。我不打算详细说明它们是如何工作的,我只想提一下我发现使用它们是多么容易——与几年前我纠结的 Java 工作线程相比,这简直是一个梦想。如果你有兴趣,可以参加官方的 Golang 之旅。

点击这里这里阅读更多关于 Go 的并发性

构建/运行/打包很简单

  • go run myProgram.go
  • go build myProgram.go

简单的内置命令,编译并运行您的主包,并将它们打包成一个二进制可执行文件,只需一个简单的命令就可以在任何地方部署。标志可以用来改变目标平台。

我现在很享受使用我声明的东西

围棋是编的。它也不允许你编译,除非你使用所有你声明的东西。这意味着你声明的每一个变量、包和函数都必须以某种方式使用,否则它会对你大喊大叫,直到你删除它们。一开始,我承认我讨厌这样——我是一名 JavaScript 开发人员,有时我只是写一些随后要删除的代码,以一种仓促的方式制作原型,调试正在发生的事情等等——你不能用 Golang 做到这一点,这让我思考我正在做的事情,并从一开始就让我的代码更整洁。

整理想法

显然,Go 并不总是每次都快 6250%,它只是碰巧在我的用例中工作得非常好,因为需要并发的数字处理——然而,我喜欢这门语言的其他事情已经被融入其中,对我来说还没有发生偏差。到目前为止,我是一个大粉丝,所以我计划继续使用它作为我的附带项目,如果适用的话

我还没有提到它的其他优点——测试、基准测试、不可思议的内置 HTTP 服务器等等。我只想谈谈我的发现,并强调有时 Node.js 并不总是答案。

上手很快,很容易上手,运行的时候快得像他妈的一样但是有点严格,没关系。

至于文中提到的代码,如果大家有兴趣我会贴上来,但是使用我的 lib 的 API 还没有启动(我很忙好吗?)所以一直没有开源。

想学围棋?

喜欢我的漫谈吗?在我的Twitter上关注我,观看我的围棋旅程,或者在我的 个人网站 上关注我的业余项目。💻

黑客中午是黑客如何开始他们的下午。我们是 @AMI 家庭的一员。我们现在接受投稿,并乐意讨论广告&赞助机会。

如果你喜欢这个故事,我们推荐你阅读我们的最新科技故事趋势科技故事。直到下一次,不要把世界的现实想当然!


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除