воскресенье, 27 сентября 2026 г.

read "the anatomy of go"

As you can expect if book about language with deliberately castrated syntax (even python has something similar to ternary operator btw) has 864 pages - it detailed everything about it's runtime. The only couple of missed things are

  1. integration with CGO
  2. generic methods - but they were introduced in version 1.27 month ago

I personally especially appreciated chapter 7 about integration of GC into native code with multithreading - with detailed description of what happened between "stop the world" and end of sweeping phase

So if you doing occasionally RE of go binaries - this book is absolutely Must Read

And now my cynical thoughts about go language

Pros

Idea of usermode threads scheduling + polling of sockets is very good and allows processing of network traffic with minimal latency (although I have a vague doubt that it was stolen from Erlang)

functions are first-class citizens and this allows to do things like fp-go (sadly practically no one uses it anyway)

Cons

I personally think that biggest flaw in design of go is lack of normal macros allowing modification of AST. Having such macros lets you write your own syntax with blackjack and patter matching

io_uring support looks unorganic- there are lots of 3rd party libraries but no embedding in language itself like they done with sockets polling. I think this is very strange - the run-time already has almost all code for it in Windows IO Completion processing logic

go lang implements it's own codegen - no lLVM or other monsters. At one hand this allows very fast compilation, but on other - it means that they lack of SSE/AVX (or generally speaking - automatic loop vectorization)

Implementation of generics is weird. Сommon objection against C++ VTBLs is that indirect calls cause code cache miss. Ok, but golang went even further - they have two calls for generics:

  1. first for interface dictionary loading
  2. second for shapes

Poor stack management - especially for recursive functions. They manage size of stack for every function call and in case of stack enlargement

  1. allocate new memory for stack
  2. copy whole content from old stack to newly allocated memory
As you can expect this is not cheap operation, and there is good question - do you really need to have for each frame contiguous region of memory? Highly likely that better solution would be chain of more short stack frames each allocated in heap at least for cold paths/recursive calls

defered code executes at end of function - and so it can't be used as C++ RAII

PGO is very limited  - for example they have hardcoded table class_to_size consisting of 67 elements and describing the sizes of pools for allocated objects. The authors provide no explanation as to why they chose precisely these sizes, but PGO could collect statistics about allocations of you application and made new table tailored specially for you

Комментариев нет:

Отправить комментарий