5 ms·
I regularly write Go code and I mostly enjoy programming in the language, but this post captures nothing important about what makes writing code in Go pleasurab
by hsn915 5y ago
I regularly write Go code and I mostly enjoy programming in the language, but this post captures nothing important about what makes writing code in Go pleasurable.
Having biultin library features is nice but is not the reason. Python also has a lot of builtin library features, but I don't enjoy working with it.
Static typing matters a great deal, but Java is also statically typed yet I don't enjoy working with it.
For me I think what makes Go pleasurable to write in is that it has structs with value semantics and it also has pointers, and it also has none of the recent (incorrectly labeled "modern") ideas such as enfoced null-checking or enforced error handling.
I can write the code in a very direct and straight forward way. I can decide myself how much abstraction to introduce. I can decide myself which errors are worth handling and which are not.
I can write functions that take complicated arguments as structs without worrying about how it will degrade performance. Because structs have value semantics, creating an instance of a struct will not trigger a heap allocation unless you return a pointer to it or let it escape the current scope via other means.
This matters a lot because a lot of performance degradation in other languages comes not only from being interpreted but from the model of programming that requires lots of tiny allocation.
Another thing that makes go pleasurable is that a package is well defined and you can import packages written by other people. But that's only secondary IMO.
Go's performance is reasonable but it's far from C/C++ level. I think a well written server in C/C++ can outperform a go webserver by a factor of 10. That said, Go is about 40x faster than Python so that's great, and it means you can write a program in Go and run it on a single machine to get the same performance to a website written in Python and hosted on 40 web servers with an insane infrastructure and requires an entire team to manage.
That said, the language also has some warts, such as lack of real typed enums that can be introspected. For example, there's currently no way to dynamically introspect an enum type and find out all the defined values/constants. You must resort to code generation.
Also the lack of generics, but hopefully those will land soon (within a year from now, if nothing goes wrong).
But, what the language lacks in features, it compensates for in tooling.
No where else have I seen a language that makes it such a breeze to cross compile. I can write code on my macbook and compile it for linux to get a valid linux executable binary that I can then `scp` to a server and have it running right away.
The compiler speed is not the greatest but it's reasonable compared to pretty much everything else out there.
- 37ef_ced3 5y agoIn my experience, the performance of carefully written Go is not far from the performance of C. Perhaps between a factor of 1.5x and 2x slower, if that. Otherwise, I agree with your comments.
- hsn915 5y agoCarefully written Go vs uncarefully written C? Sure. Carefully written Go vs carefully written C? I still think C would win by a factor of 10. Like I said, most slowness comes from memory access and fragmentation. In C you can use strategies like arena allocations. In Go you cannot turn of the GC.
- 37ef_ced3 5y agoIf you want to build a custom allocator (use freelists and vectors of types) you can do all of that in Go and C. There's nothing stopping you from writing custom memory allocators in Go.
- mxschumacher 5y agoI'm always slightly confused by the language speed comparisons for I/O heavy applications like networked services. On the one side you are taking in, for example, HTTP requests, on the other you are talking to a database, maybe some other networked APIs. A caching layer picks up plenty of load - how often is the program really cpu-bound here? For me fastAPI [0] and async Python call the performance statements into question; good to run some benchmarks with real world use cases [0] https://fastapi.tiangolo.com/async/ https://fastapi.tiangolo.com/async/
- hsn915 5y agoI'm confused by "I/O heavy applications". This is a reality: I can server thousands of concurrent connections using a single machine in a server program written in Go. Can you do the same thing in Python or Ruby? No. Something to be noted: when your host language is slow (like Python) you almost have no choice but to make your application I/O heavy. What do I mean? Your application needs feature X. Your choices: - Implement X in your codebase. - Run a separate program XY that sort of does X, host it on the same or a different machine, and let your actual program talk to XY over a socket connection. When I write in Go, I just implement X in my program. No I/O, just regular code. When you write in Python, this option is out the window, so you have no choice but to run XY and talk to it over a socket. An easy to understand example is a cache. In Go I can just cache things in memory. In your python project you have to use Redis. So it looks to you like the problem domain is inherenty I/O heavy. Yes there's a lot of I/O involved, but that's mostly: - TCP connections from clients (HTTP) - Saving data to permanent storage Another thing you can do when you write in Go vs Python is you can move computations from the database server to your own code. See, there's this thing that happens in Python code where, because your host language is slow, you lean heavily on your (Postgres?) database to pull up the heavy weight. So what happens? Your database becomes a bottle neck. A lot of the heavy computations that you push to your database can be performed a lot faster in your own code base .... if only you weren't hosting yourself in a slow language. This is not some theoretical bullshit. I've seen this manifest in real world applications.