Golang vs. Python: Comparing Performance and Benchmarks
Hello, my name is Vadym, and this is my story about how I started learning Go, what it felt like compared to Python (the language I currently use at work), and benchmarking.
I believe that every developer should learn constantly to be good at what they do. And it’s not only about knowing new frameworks, databases, or platforms like AWS Lambda. Itβs about knowing how the services you use from day to day interact with each other, differentiate when your favorite language uses a link to an object or a copy of the object, and many other things.
I’ve been using Python as my main language for writing production code for 10 years. But even as a devoted Python developer, Iβve tried different languages over time. I like to learn new languages, because I might pick up something for my daily work β even from ones I wonβt use or from languages I donβt really like, such as Ruby or Java. Also, itβs not very important for me to learn new languages only. I like to spend time on old and rarely used languages as well. For example, Iβve tried Lisp for more than writing a config for Emacs. I also like Erlang a lot, but itβs not very popular nowadays.
As I mentioned above, the Django Stars development team has extensive experience with Python in various projects. In this little guide, I would like to compare the performance of Golang vs Python and push head-on other benchmarks of these programming languages.
Getting to Know Go
Before comparing Go vs Python performance, it is worth telling a little more about Golang, or rather about my acquaintance with it. A few weeks ago, I started searching for a new language to learn. First of all, I started investigating Elixir, as I like Erlang, but I don’t really like it after reading the tutorial. After a few days, I settled on Go, as Iβve heard a lot about this language from different sources. At first sight, the language didnβt seem complicated, but it required a different approach to the application architecture than Python, for example. So I decided to delve deeper into Go.
Step One
What I did first was to have a look at the Go community. The Go community has an amazing tutorial that teaches you a lot about the language right away. I believe it’s a great starting point: www.tour.golang.org. The tutorial is split into three sections, plus a welcome section:
- Basic shows you the basics of Go syntax, how to work with variables and functions, flow control statements and more complex types.
- Method and interfaces explains how to create and implement interfaces.
- Concurrency in Go explains all the basics on the subject.
All of these sections have simple practical tasks that cover what you have learned.
Step Two
The next step to learning Go was watching presentations. The best one (in my opinion) is Go Concurrency Patterns by Rob Pike. This presentation is easy to watch and very motivating. I also recommend watching YouTube suggestions based on this video.
Step Three
Before I tried creating my own simple application (and started a Go vs. Python apps battle), I had studied another great tutorial β Learn Go with tests. This tutorial explains Go and how to write code using the methodology of test-driven development.
After going through all these tutorials and videos, I decided to finally try to write a simple application with Go myself. I chose to write a URL-shortener service, similar to bit.ly or goo.gl, but simpler, without statistics and UI. (I may add them in the future.)
First, I attempted to create a channel with a set of prepared short strings to identify long URLs. It was an excellent exercise for working with channels and goroutines. But for now, I don’t use this code in service and generate short strings each time I need to store a long URL. Next, I started writing code for the application β short string generation code with tests at first. When I started thinking about storage, I got stuck. This happened because I didn’t understand how to split my code correctly. For me, the answer was in the project layout of the Go standard library and in checking out some popular Go libraries and applications. Also, I found Go modules that werenβt highlighted in any of the tutorials.
.
βββ api
β βββ openapi.yaml
βββ build
β βββ ci
β β βββ .travis.yml
β βββ Dockerfile
β βββ docker-compose.yml
βββ internal
β βββ generator
β β βββ generator.go
β β βββ generator_test.go
β βββ storage
β βββ redis_storage.go
β βββ redis_storage_test.go
β βββ simple_storage.go
β βββ simple_storage_test.go
β βββ storage.go
βββ third_party
β βββ locustfile.py
β βββ redoc-static.html
β βββ wrk_post.lua
βββ .gitignore
βββ .travis.yml -> build/ci/.travis.yml
βββ LICENSE
βββ README.md
βββ go.mod
βββ go.sum
βββ main.go
I started my second attempt by describing OpenAPI schema for my API. Then I copied the generating function from the previous code and started working on URL storage. As I was researching project layouts for Go applications, I found Bolt β a simple key-value storage library written in Go. The description of this library says that the storage can be used to store a large amount of data. I decided to try it, as the approach I used allowed me to easily replace this library with different data storage without changing a lot of code.
Benchmarking and Go vs. Python Performance
My first application in Go is ready, and to compare Golang vs. Python, I want to do a benchmark test. Usually, I use wrk to do so, but this time I decided to use Locust. With Locust, it’s easier to create a test that will use all the endpoints I have at the same time. I was surprised when the result was about 43 requests per second, which is a quite small number. My first assumption was that the number was so small because the storage uses only files on my disk. I decided to write the same application in Python using asyncio, aiohttp and aioredis as storage, check the results, and then implement storage that uses Redis in a Go application.
And it worked! I got the same result as the performance benchmark test for both applications in Python and Go. First of all, I ran wrk to test the API endpoint to retrieve the long URL by short string. It was the right decision, because I received different results. The Go application was 9 times faster than Python, and Python did more than 43 requests in a second. The numbers were now about 280 requests per second for Python, and 2500 for Go. Which, from my point of view, is closer to the truth. Locust probably suggests having slaves to do proper testing instead of using fork/threads, and that’s why 43 requests per second is the limit for Locust in the current setup.
Go + Bolt (GET) | Python + Redis (GET) |
Running 30s test @ http://rpi:5000/api/v1/url/aaaa | Running 30s test @ http://rpi:5000/api/v1/url/aaaa |
* printout from final tests
The next test was for an API for storing long URLs. It showed that my Go application can handle about 20 requests per second. This confirmed my expectations. After this test, I did the storage implementation that uses Redis and ran all the tests again using wrk.
Below, you can see the chart with the test results and compare Go vs. Python speed. I used Raspberry Pi 3 B+ as a platform for the application and a laptop with i7 and 16 Gb of RAM to run wrk (Locust had the same configuration). It was an intentional decision to use Raspberry Pi, to give the laptop on which I ran the test more power.
All these results are from wrk that has been working with 12 threads and 400 connections for 30 seconds. The numbers are the total amount for all the threads, not for just one. If youβre interested in the raw wrk results, please follow this link.
My Personal Results
To be honest, the application I wrote in Python and ran with the help of Gunicorn from the beginning had worse results than I showed you. It gave approx. 360 requests per second. But as soon as I had an increased number of Gunicorn workers from 2 (default) to 4, the results doubled. There are 4 CPUs on Raspberry Pi, and to have more workers than CPUs could cause worse results.
When comparing Golang vs. Python performance, I may have gotten better results for the Go application, but I don’t know enough about how to run a Go application in production.
In conclusion, I want to say that I’m very excited about Go. The last time I was so excited about a programming language was when I started learning Python. For an agile company that makes web applications, Python is probably a better choice right now, as more developers know Python. The most impressive thing about Python is its huge community.
In addition, I believe that to write applications in Go, developers should think more about application design than they do when they use other languages like Python. This can be a decisive factor when comparing Go and Python. Otherwise, they wonβt be able to make changes and extend the application functionality in the future. Or it might be extremely difficult. By the way, hereβs the repository with my Go application that I hope to work on and extend in the future: https://github.com/Quard/gosh.
And one last thing. Did any of you have similar experiences with learning either of these languages? What were your insights?
If you are looking for a dedicated team for your project or want to consult on software development, contact Django Stars.
- Which is fast in web development Go or Python?
Golang is known for its fast performance and efficient use of resources. It is a compiled language, which means that the code is translated into machine-readable code before it is executed, resulting in faster execution compared to interpreted languages such as Python. On the other hand, Python has a lot of libraries, frameworks, and modules that you can use to optimize performance and speed up the development process.
When comparing Golang vs. Python performance, I may have gotten better results for the Go application, but I donβt know enough about how to run a Go application in production.
- How to get started learning the Go programming language?
- To start learning the programming language Go, the first step might be to look at the Go community. The Go community has an amazing tutorial that helps you learn a lot about the language. It includes simple practical tasks that cover what you have learned. After completing the tutorial, you can proceed to view presentations like Go Concurrency Patterns by Rob Pike and Learn Go with tests. Once you have a good understanding of the basics, you can try creating a simple application yourself.
- Why is Python better for blockchain than Golang?
- Python is better for blockchain development than Golang due to its ease of use, readability, and developed community. Python has a rich set of libraries and frameworks that support blockchain development, and its simplicity and flexibility make it a good choice for prototyping and testing ideas. Golang is good for high-performance, high-concurrency web applications, but its ecosystem is not as rich as Python's, and its developer community is not as large.
- Comparing Golang vs Python in 2023, which language is preferred for AI apps?
- It depends on the specific use case and requirements of the AI application. Both Go and Python have their strengths and weaknesses. Go is known for its performance and concurrency capabilities, making it well-suited for high-performance, low-latency systems. Python, on the other hand, has a vast ecosystem of libraries and frameworks for machine learning and data science, making it a popular choice for these types of applications. Ultimately, the choice of language will depend on the specific requirements of the AI application and the development team's expertise.