菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
75
0

为什么我们放弃 Python 而选择 Go?(getstream.io 的架构变迁)

原创
05/13 14:22
阅读数 852

更新于2019年5月14日, 为了更好的反映过去两年 Go 的提升(包管理,更好的性能,更快的编译时间和更成熟的生态系统)。 切换到新的编程语言总归来说是一大步改动,特别是团队就你一人有该语言的使用经验。年初,我们把 Stream’s 的主要编程语言从 Python 切换到 Go。这篇文章将解释为甚我们决定放弃Python并转而使用Go。

理由一、性能

Go 很快!Go 是相当的快。其性能比肩 Java 或 C++。在我们的用例中,Go 通常比 Python 快40倍。这里有一个 Go vs Python 小的基准比较游戏。

理由二、语言性能很重要

对于大部分应用来说,编程语言只是应用程序和数据库之间的粘合剂。语言本身的表现通常无关紧要。然而,Stream 一个提供 API 的程序,为 700 家公司和 5 亿多最终用户提供 动态流实时聊天 的基础设施。多年来,我们一直在优化 Cassandra、PostgreSQL、Redis 等,但最终,达到了所使用语言的极限。Python 是一种很棒的语言,但是对于序列化/反序列化、排名和聚合等用例来说,它的性能相当缓慢。我们经常遇到性能问题,Cassandra 需要 1 毫秒来检索数据,而 Python 则需要 10 毫秒来将其转换为对象。

理由三、开发人员的生产率和创新能力不足

package main
type openWeatherMap struct{}
func (w openWeatherMap) temperature(city string) (float64, error) {
    resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city)
    if err != nil {
        return 0, err
    }
    defer resp.Body.Close()
    var d struct {
        Main struct {
            Kelvin float64 json:"temp"
        } json:"main"
    }
    if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
        return 0, err
    }
    log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)
    return d.Main.Kelvin, nil
}

即便是 Go 语言的新手,在阅读这小代码片段时,也不会出现难以理解的地方。它演示了多赋值函数,数据结构,指针,格式和内置的 HTTP 库。刚开始编程时,我总是喜欢使用 Python 的高级功能。使用 Python 编码时你可以发挥创意。例如,你可以:

  • 在代码初始化时使用 MetaClasses 自注册类
  • 交换 True 和 False
  • 将函数添加到内置函数列表中
  • 通过魔术方法重载运算符
  • 通过 @property 装饰器将函数用作属性

这些功能很有趣,但是正如大多数程序员所同意的那样,它们通常使代码可读性降低,使你难以理解别人的工作。 Go 迫使您坚持基础知识。这样一来,您就可以轻松阅读任何人的代码并立即了解发生了什么。 注:到底有多“简单”取决于您的用例。如果您想创建基本的CRUD API,我仍然建议您使用Django + DRF 或 Rails。

Reason 4 - Concurrency & Channels

As a language, Go tries to keep things simple. It doesn’t introduce many new concepts. The focus is on creating a simple language that is incredibly fast and easy to work with. The only area where it does get innovative is goroutines and channels. (To be 100% correct the concept of CSP started in 1977, so this innovation is more of a new approach to an old idea.) Goroutines are Go’s lightweight approach to threading, and channels are the preferred way to communicate between goroutines. Goroutines are very cheap to create and only take a few KBs of additional memory. Because Goroutines are so light, it is possible to have hundreds or even thousands of them running at the same time. You can communicate between goroutines using channels. The Go runtime handles all the complexity. The goroutines and channel-based approach to concurrency makes it very easy to use all available CPU cores and handle concurrent IO - all without complicating development. Compared to Python/Java, running a function on a goroutine requires minimal boilerplate code. You simply prepend the function call with the keyword “go”:

package main
import (
    "fmt"
    "time"
)
func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}
func main() {
    go say("world")
    say("hello")
}

https://tour.golang.org/concurrency/1 Go’s approach to concurrency is very easy to work with. It’s an interesting approach compared to Node where the developer has to pay close attention to how asynchronous code is handled. Another great aspect of concurrency in Go is the race detector. This makes it easy to figure out if there are any race conditions within your asynchronous code.

Knock knock Race condition Who's there?

— I Am Devloper (@iamdevloper) November 11, 2013

Here are a few good resources to get started with Go and channels:

Reason 5 - Fast Compile Time

Our largest micro service written in Go currently takes 4 seconds to compile. Go’s fast compile times are a major productivity win compared to languages like Java and C++ which are famous for sluggish compilation speed. I like sword fighting, but it’s even nicer to get things done while I still remember what the code is supposed to do:

Reason 6 - The Ability to Build a Team

First of all, let’s start with the obvious: there are not as many Go developers compared to older languages like C++ and Java. According to StackOverflow38% of developers know Java, 19.3% know C++ and only 4.6% know Go. GitHub data shows a similar trend: Go is more widely used than languages such as Erlang, Scala and Elixir, but less popular than Java and C++. Fortunately, Go is a very simple and easy to learn language. It provides the basic features you need and nothing else. The new concepts it introduces are the “defer” statement and built-in management of concurrency with “go routines” and channels. (For the purists: Go isn’t the first language to implement these concepts, just the first to make them popular.) Any Python, Elixir, C++, Scala or Java dev that joins a team can be effective at Go within a month because of its simplicity. We’ve found it easier to build a team of Go developers compared to many other languages. If you’re hiring people in competitive ecosystems like Boulder and Amsterdam this is an important benefit.

Reason 7 - Strong Ecosystem

For a team of our size (~20 people) the ecosystem matters. You simply can’t create value for your customers if you have to reinvent every little piece of functionality. Go has great support for the tools we use. Solid libraries were already available for Redis, RabbitMQ, PostgreSQL, Template parsing, Task scheduling, Expression parsing and RocksDB. Go’s ecosystem is a major win compared to other newer languages like Rust or Elixir. It’s of course not as good as languages like Java, Python or Node, but it’s solid and for many basic needs you’ll find high-quality packages already available.

Reason 8 - Gofmt, Enforced Code Formatting

Let’s start with what is Gofmt? And no, it’s not a swear word. Gofmt is an awesome command line utility, built into the Go compiler for formatting your code. In terms of functionality it's very similar to Python’s autopep8. While the show Silicon Valley portrays otherwise, most of us don’t really like to argue about tabs vs spaces. It’s important that formatting is consistent, but the actual formatting standard doesn’t really matter all that much. Gofmt avoids all of this discussion by having one official way to format your code.

Reason 9 - gRPC and Protocol Buffers

Go has first-class support for protocol buffers and gRPC. These two tools work very well together for building microservices which need to communicate via RPC. You only need to write a manifest where you define the RPC calls that can be made and what arguments they take. Both server and client code are then automatically generated from this manifest. This resulting code is both fast, has a very small network footprint and is easy to use. From the same manifest, you can generate client code for many different languages even, such as C++, Java, Python and Ruby. So, no more ambiguous REST endpoints for internal traffic, that you have to write almost the same client and server code for every time. .

缺点 1 - 缺少框架

Go 缺少一个主流的框架,比如 Ruby 的 Rails、Python 的 Django 或 PHP 的 Laravel。这是 Go 社区中的一个热议话题,因为许多人主张不应该从使用框架开始。我完全同意在某些用例中是这样的。但是,如果有人想构建一个简单的CRUD API,那么他们将更容易使用 Django/DJRF、Rails、Laravel 或 Phoenix .

更新: 正如评论指出的 目前有几个不错的 Go 框架。RevelIrisEchoMacaronBuffalo 似乎都是不错的选项。

对于 Stream 的用例,我们更喜欢不使用框架。然而,对于许多希望提供简单 CRUD API 的新项目来说,缺少一个主导框架将是一个严重的缺点。

Disadvantage 2 - Error Handling

Go handles errors by simply returning an error from a function and expecting your calling code to handle the error (or to return it up the calling stack). While this approach works, it’s easy to lose scope of what went wrong to ensure you can provide a meaningful error to your users. The errors package solves this problem by allowing you to add context and a stack trace to your errors. Another issue is that it’s easy to forget to handle an error by accident. Static analysis tools like errcheck and megacheck are handy to avoid making these mistakes. While these workarounds work well it doesn’t feel quite right. You’d expect proper error handling to be supported by the language.

Disadvantage 3 - Package Management

Update: Go's package management has come a long way since this post was written. Go modules are an effective solution, the only issue I've seen with them is that they break some static analysis tools like errcheck. Here's a tutorial for learning to use Go using Go modules.   Go’s package management is by no means perfect. By default, it doesn’t have a way to specify a specific version of a dependency and there’s no way to create reproducible builds. Python, Node and Ruby all have better systems for package management. However, with the right tools, Go’s package management works quite well. You can use Dep to manage your dependencies to allow specifying and pinning versions. Apart from that, we’ve contributed an open-source tool called VirtualGo which makes it easier to work on multiple projects written in Go.

Python vs Go

Update: The performance difference between Python and Go increased since this post was written. (Go became faster and Python didn't) One interesting experiment we conducted was taking our ranked feed functionality in Python and rewriting it in Go. Have a look at this example of a ranking method:

{
    "functions": {
        "simple_gauss": {
            "base": "decay_gauss",
            "scale": "5d",
            "offset": "1d",
            "decay": "0.3"
        },
        "popularity_gauss": {
            "base": "decay_gauss",
            "scale": "100",
            "offset": "5",
            "decay": "0.5"
        }
    },
    "defaults": {
        "popularity": 1
    },
    "score": "simple_gauss(time)*popularity"
}

Both the Python and Go code need to do the following to support this ranking method:

  1. Parse the expression for the score. In this case, we want to turn this string “simple_gauss(time)*popularity” into a function that takes an activity as input and returns a score as output.
  2. Create partial functions based on the JSON config. For example, we want “simple_gauss” to call “decay_gauss” with a scale of 5 days, offset of 1 day and a decay factor of 0.3.
  3. Parse the “defaults” configuration so you have a fallback if a certain field is not defined on an activity.
  4. Use the function from step 1 to score all activities in the feed.

Developing the Python version of the ranking code took roughly 3 days. That includes writing the code, unit tests and documentation. Next, we’ve spent approximately 2 weeks optimizing the code. One of the optimizations was translating the score expression (simple_gauss(time)*popularity) into an abstract syntax tree. We also implemented caching logic which pre-computed the score for certain times in the future. In contrast, developing the Go version of this code took roughly 4 days. The performance didn’t require any further optimization. So while the initial bit of development was faster in Python, the Go based version ultimately required substantially less work from our team. As an added benefit, the Go code performed roughly 40 times faster than our highly-optimized Python code. Now, this is just a single example of the performance gains we’ve experienced by switching to Go. It is, of course, comparing apples to oranges:

  • The ranking code was my first project in Go
  • The Go code was built after the Python code, so the use case was better understood
  • The Go library for expression parsing was of exceptional quality

Your mileage will vary. Some other components of our system took substantially more time to build in Go compared to Python. As a general trend, we see that developing Go code takes slightly more effort. However, we spend much less time optimizing the code for performance.

Elixir vs Go - The Runner Up

Another language we evaluated is Elixir. Elixir is built on top of the Erlang virtual machine. It’s a fascinating language and we considered it since one of our team members has a ton of experience with Erlang. For our use cases, we noticed that Go’s raw performance is much better. Both Go and Elixir will do a great job serving thousands of concurrent requests. However, if you look at individual request performance, Go is substantially faster for our use case. Another reason why we chose Go over Elixir was the ecosystem. For the components we required, Go had more mature libraries whereas, in many cases, the Elixir libraries weren’t ready for production usage. It’s also harder to train/find developers to work with Elixir. These reasons tipped the balance in favor of Go. The Phoenix framework for Elixir looks awesome though and is definitely worth a look.

Conclusion

Go is a very performant language with great support for concurrency. It is almost as fast as languages like C++ and Java. While it does take a bit more time to build things using Go compared to Python or Ruby, you’ll save a ton of time spent on optimizing the code. We have a small development team at Stream powering feeds and chat for over 500 million end users. Go’s combination of a great ecosystemeasy onboarding for new developers, fast performancesolid support for concurrency and a productive programming environment make it a great choice. Stream still leverages Python for our dashboard, site and machine learning for personalized feeds. We won’t be saying goodbye to Python anytime soon, but going forward all performance-intensive code will be written in Go. Our new Chat API is also written entirely in Go. If you want to learn more about Go check out the blog posts listed below. To learn more about Stream, this interactive tutorial is a great starting point.

本文章首发在 猿圈.com 网站上。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。


更新于2019年5月14日, 为了更好的反映过去两年 Go 的提升(包管理,更好的性能,更快的编译时间和更成熟的生态系统)。 切换到新的编程语言总归来说是一大步改动,特别是团队就你一人有该语言的使用经验。年初,我们把 Stream’s 的主要编程语言从 Python 切换到 Go。这篇文章将解释为甚我们决定放弃Python并转而使用Go。

理由一、性能

Go 很快!Go 是相当的快。其性能比肩 Java 或 C++。在我们的用例中,Go 通常比 Python 快40倍。这里有一个 Go vs Python 小的基准比较游戏。

理由二、语言性能很重要

对于大部分应用来说,编程语言只是应用程序和数据库之间的粘合剂。语言本身的表现通常无关紧要。然而,Stream 一个提供 API 的程序,为 700 家公司和 5 亿多最终用户提供 动态流实时聊天 的基础设施。多年来,我们一直在优化 Cassandra、PostgreSQL、Redis 等,但最终,达到了所使用语言的极限。Python 是一种很棒的语言,但是对于序列化/反序列化、排名和聚合等用例来说,它的性能相当缓慢。我们经常遇到性能问题,Cassandra 需要 1 毫秒来检索数据,而 Python 则需要 10 毫秒来将其转换为对象。

理由三、开发人员的生产率和创新能力不足

package main
type openWeatherMap struct{}
func (w openWeatherMap) temperature(city string) (float64, error) {
    resp, err := http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city)
    if err != nil {
        return 0, err
    }
    defer resp.Body.Close()
    var d struct {
        Main struct {
            Kelvin float64 json:"temp"
        } json:"main"
    }
    if err := json.NewDecoder(resp.Body).Decode(&d); err != nil {
        return 0, err
    }
    log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)
    return d.Main.Kelvin, nil
}

即便是 Go 语言的新手,在阅读这小代码片段时,也不会出现难以理解的地方。它演示了多赋值函数,数据结构,指针,格式和内置的 HTTP 库。刚开始编程时,我总是喜欢使用 Python 的高级功能。使用 Python 编码时你可以发挥创意。例如,你可以:

  • 在代码初始化时使用 MetaClasses 自注册类
  • 交换 True 和 False
  • 将函数添加到内置函数列表中
  • 通过魔术方法重载运算符
  • 通过 @property 装饰器将函数用作属性

这些功能很有趣,但是正如大多数程序员所同意的那样,它们通常使代码可读性降低,使你难以理解别人的工作。 Go 迫使您坚持基础知识。这样一来,您就可以轻松阅读任何人的代码并立即了解发生了什么。 注:到底有多“简单”取决于您的用例。如果您想创建基本的CRUD API,我仍然建议您使用Django + DRF 或 Rails。

Reason 4 - Concurrency & Channels

As a language, Go tries to keep things simple. It doesn’t introduce many new concepts. The focus is on creating a simple language that is incredibly fast and easy to work with. The only area where it does get innovative is goroutines and channels. (To be 100% correct the concept of CSP started in 1977, so this innovation is more of a new approach to an old idea.) Goroutines are Go’s lightweight approach to threading, and channels are the preferred way to communicate between goroutines. Goroutines are very cheap to create and only take a few KBs of additional memory. Because Goroutines are so light, it is possible to have hundreds or even thousands of them running at the same time. You can communicate between goroutines using channels. The Go runtime handles all the complexity. The goroutines and channel-based approach to concurrency makes it very easy to use all available CPU cores and handle concurrent IO - all without complicating development. Compared to Python/Java, running a function on a goroutine requires minimal boilerplate code. You simply prepend the function call with the keyword “go”:

package main
import (
    "fmt"
    "time"
)
func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}
func main() {
    go say("world")
    say("hello")
}

https://tour.golang.org/concurrency/1 Go’s approach to concurrency is very easy to work with. It’s an interesting approach compared to Node where the developer has to pay close attention to how asynchronous code is handled. Another great aspect of concurrency in Go is the race detector. This makes it easy to figure out if there are any race conditions within your asynchronous code.

Knock knock Race condition Who's there?

— I Am Devloper (@iamdevloper) November 11, 2013

Here are a few good resources to get started with Go and channels:

Reason 5 - Fast Compile Time

Our largest micro service written in Go currently takes 4 seconds to compile. Go’s fast compile times are a major productivity win compared to languages like Java and C++ which are famous for sluggish compilation speed. I like sword fighting, but it’s even nicer to get things done while I still remember what the code is supposed to do:

Reason 6 - The Ability to Build a Team

First of all, let’s start with the obvious: there are not as many Go developers compared to older languages like C++ and Java. According to StackOverflow38% of developers know Java, 19.3% know C++ and only 4.6% know Go. GitHub data shows a similar trend: Go is more widely used than languages such as Erlang, Scala and Elixir, but less popular than Java and C++. Fortunately, Go is a very simple and easy to learn language. It provides the basic features you need and nothing else. The new concepts it introduces are the “defer” statement and built-in management of concurrency with “go routines” and channels. (For the purists: Go isn’t the first language to implement these concepts, just the first to make them popular.) Any Python, Elixir, C++, Scala or Java dev that joins a team can be effective at Go within a month because of its simplicity. We’ve found it easier to build a team of Go developers compared to many other languages. If you’re hiring people in competitive ecosystems like Boulder and Amsterdam this is an important benefit.

Reason 7 - Strong Ecosystem

For a team of our size (~20 people) the ecosystem matters. You simply can’t create value for your customers if you have to reinvent every little piece of functionality. Go has great support for the tools we use. Solid libraries were already available for Redis, RabbitMQ, PostgreSQL, Template parsing, Task scheduling, Expression parsing and RocksDB. Go’s ecosystem is a major win compared to other newer languages like Rust or Elixir. It’s of course not as good as languages like Java, Python or Node, but it’s solid and for many basic needs you’ll find high-quality packages already available.

Reason 8 - Gofmt, Enforced Code Formatting

Let’s start with what is Gofmt? And no, it’s not a swear word. Gofmt is an awesome command line utility, built into the Go compiler for formatting your code. In terms of functionality it's very similar to Python’s autopep8. While the show Silicon Valley portrays otherwise, most of us don’t really like to argue about tabs vs spaces. It’s important that formatting is consistent, but the actual formatting standard doesn’t really matter all that much. Gofmt avoids all of this discussion by having one official way to format your code.

Reason 9 - gRPC and Protocol Buffers

Go has first-class support for protocol buffers and gRPC. These two tools work very well together for building microservices which need to communicate via RPC. You only need to write a manifest where you define the RPC calls that can be made and what arguments they take. Both server and client code are then automatically generated from this manifest. This resulting code is both fast, has a very small network footprint and is easy to use. From the same manifest, you can generate client code for many different languages even, such as C++, Java, Python and Ruby. So, no more ambiguous REST endpoints for internal traffic, that you have to write almost the same client and server code for every time. .

缺点 1 - 缺少框架

Go 缺少一个主流的框架,比如 Ruby 的 Rails、Python 的 Django 或 PHP 的 Laravel。这是 Go 社区中的一个热议话题,因为许多人主张不应该从使用框架开始。我完全同意在某些用例中是这样的。但是,如果有人想构建一个简单的CRUD API,那么他们将更容易使用 Django/DJRF、Rails、Laravel 或 Phoenix .

更新: 正如评论指出的 目前有几个不错的 Go 框架。RevelIrisEchoMacaronBuffalo 似乎都是不错的选项。

对于 Stream 的用例,我们更喜欢不使用框架。然而,对于许多希望提供简单 CRUD API 的新项目来说,缺少一个主导框架将是一个严重的缺点。

Disadvantage 2 - Error Handling

Go handles errors by simply returning an error from a function and expecting your calling code to handle the error (or to return it up the calling stack). While this approach works, it’s easy to lose scope of what went wrong to ensure you can provide a meaningful error to your users. The errors package solves this problem by allowing you to add context and a stack trace to your errors. Another issue is that it’s easy to forget to handle an error by accident. Static analysis tools like errcheck and megacheck are handy to avoid making these mistakes. While these workarounds work well it doesn’t feel quite right. You’d expect proper error handling to be supported by the language.

Disadvantage 3 - Package Management

Update: Go's package management has come a long way since this post was written. Go modules are an effective solution, the only issue I've seen with them is that they break some static analysis tools like errcheck. Here's a tutorial for learning to use Go using Go modules.   Go’s package management is by no means perfect. By default, it doesn’t have a way to specify a specific version of a dependency and there’s no way to create reproducible builds. Python, Node and Ruby all have better systems for package management. However, with the right tools, Go’s package management works quite well. You can use Dep to manage your dependencies to allow specifying and pinning versions. Apart from that, we’ve contributed an open-source tool called VirtualGo which makes it easier to work on multiple projects written in Go.

Python vs Go

Update: The performance difference between Python and Go increased since this post was written. (Go became faster and Python didn't) One interesting experiment we conducted was taking our ranked feed functionality in Python and rewriting it in Go. Have a look at this example of a ranking method:

{
    "functions": {
        "simple_gauss": {
            "base": "decay_gauss",
            "scale": "5d",
            "offset": "1d",
            "decay": "0.3"
        },
        "popularity_gauss": {
            "base": "decay_gauss",
            "scale": "100",
            "offset": "5",
            "decay": "0.5"
        }
    },
    "defaults": {
        "popularity": 1
    },
    "score": "simple_gauss(time)*popularity"
}

Both the Python and Go code need to do the following to support this ranking method:

  1. Parse the expression for the score. In this case, we want to turn this string “simple_gauss(time)*popularity” into a function that takes an activity as input and returns a score as output.
  2. Create partial functions based on the JSON config. For example, we want “simple_gauss” to call “decay_gauss” with a scale of 5 days, offset of 1 day and a decay factor of 0.3.
  3. Parse the “defaults” configuration so you have a fallback if a certain field is not defined on an activity.
  4. Use the function from step 1 to score all activities in the feed.

Developing the Python version of the ranking code took roughly 3 days. That includes writing the code, unit tests and documentation. Next, we’ve spent approximately 2 weeks optimizing the code. One of the optimizations was translating the score expression (simple_gauss(time)*popularity) into an abstract syntax tree. We also implemented caching logic which pre-computed the score for certain times in the future. In contrast, developing the Go version of this code took roughly 4 days. The performance didn’t require any further optimization. So while the initial bit of development was faster in Python, the Go based version ultimately required substantially less work from our team. As an added benefit, the Go code performed roughly 40 times faster than our highly-optimized Python code. Now, this is just a single example of the performance gains we’ve experienced by switching to Go. It is, of course, comparing apples to oranges:

  • The ranking code was my first project in Go
  • The Go code was built after the Python code, so the use case was better understood
  • The Go library for expression parsing was of exceptional quality

Your mileage will vary. Some other components of our system took substantially more time to build in Go compared to Python. As a general trend, we see that developing Go code takes slightly more effort. However, we spend much less time optimizing the code for performance.

Elixir vs Go - The Runner Up

Another language we evaluated is Elixir. Elixir is built on top of the Erlang virtual machine. It’s a fascinating language and we considered it since one of our team members has a ton of experience with Erlang. For our use cases, we noticed that Go’s raw performance is much better. Both Go and Elixir will do a great job serving thousands of concurrent requests. However, if you look at individual request performance, Go is substantially faster for our use case. Another reason why we chose Go over Elixir was the ecosystem. For the components we required, Go had more mature libraries whereas, in many cases, the Elixir libraries weren’t ready for production usage. It’s also harder to train/find developers to work with Elixir. These reasons tipped the balance in favor of Go. The Phoenix framework for Elixir looks awesome though and is definitely worth a look.

Conclusion

Go is a very performant language with great support for concurrency. It is almost as fast as languages like C++ and Java. While it does take a bit more time to build things using Go compared to Python or Ruby, you’ll save a ton of time spent on optimizing the code. We have a small development team at Stream powering feeds and chat for over 500 million end users. Go’s combination of a great ecosystemeasy onboarding for new developers, fast performancesolid support for concurrency and a productive programming environment make it a great choice. Stream still leverages Python for our dashboard, site and machine learning for personalized feeds. We won’t be saying goodbye to Python anytime soon, but going forward all performance-intensive code will be written in Go. Our new Chat API is also written entirely in Go. If you want to learn more about Go check out the blog posts listed below. To learn more about Stream, this interactive tutorial is a great starting point.

本文章首发在 猿圈.com 网站上。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

发表评论

0/200
75 点赞
0 评论
收藏
为你推荐 换一批