Optimize! Optimize! Optimize! • The Applied Go Weekly Newsletter 2024-01-28
Your weekly source of Go news, tips, and projects
A message to my readers: The previous issue had some problems and got delayed by over a week for many readers. Furthermore, the new platform of my mailing provider has some serious bugs. One of these bugs tricked me into re-sending the previous issue to everyone, not just to those who didn't receive it the first time. Duh.
I decided to circumvent these bugs once and forever by switching to another mailing service, Buttondown.email. This is why this issue looks different from the previous ones. On the positive side, code snippets render much better now, and the email should also show fine as plain text.
The switch required a few more days of work, that's why this issue is also delayed. Nevertheless, I hope you enjoy it!
If your working time passes slowly like a turtle trudging through peanut butter, this might be because you have to wait for slow apps to respond. Time for some optimizations! To get you started, the first two featured articles are all about optimizing for performance.
Optimizing Go code for the CPU Cache - YouTube
Every CPU core has its own local cache. For multithreaded applications, those local caches can become a bottleneck. If two threads running on different cores share data, the cores must transfer the data from one local cache to the other.
Goroutines are scheduled onto system threads dynamically and therefore cannot be pinned to specific CPU cores. In this video, William Moran explores the effects of CPU caching on the performance of Go applications.
Optimizing Go code for the CPU Cache - YouTube
From slow to SIMD: A Go optimization story
Optimization typically happens in multiple rounds. Camden Cheek describes Sourcegraph's journey in optimizing a critical dot product function, from quantizing vectors to 8-bit integers to using handwritten SIMD assembly in Go, resulting in dramatic performance improvements.
From slow to SIMD: A Go optimization story
Share your feedback about developing with Go - The Go Programming Language
Every six months, the Go Developer Survey seeks feedback from Go developers. The survey for H1 2024 is now open. Share your feedback until Feb 11th and help make Go even better!
Share your feedback about developing with Go - The Go Programming Language
Podcast corner
Backend Banter
Matt Holt, creator of the Caddy webserver, chats with Lane Wagner about the origins and unique features of Caddy, why the Caddyfile has no extension, and lots of other topics around Caddy and Matt's journey in Go programming.
Backend Banter | #037 - Caddy Chronicles with Matt Holt
Cup o' Go
Did Jonathan Hall's cat roll over his keyboard, or what's about the title of the latest Cup o' Go episode? It probably has to do with the recently declined proposal to have benchstat
optionally support ASCII-only output. Also discussed: The new range syntax, debugging Go compiler performance, and more.
Cup o' Go | 📐 ⓦide rąnge οf tøpics wíth Yarɗen Laifėnfeld as gµest hoʂt
Go Time
Episode #300 is out! The panelists look back on 8 years of Go Time and share their favorite episodes.
300 multiple choices (Go Time #300) |> Changelog
Ardan Labs Podcast
Jesús Espino talks about his work as Senior Staff Engineer at Mattermost, his transitioning to Go, and how knowledge about Go internals helps solving programming problems.
Mattermost, Go, and Tech Talk with Jesús Espino
go podcast()
In this episode, Dominic St-Pierre suggests that companies should try harder to improve their interview and onboarding processes.
go podcast() | 026: We can do better with interviews and onboarding
Stray Pointers
Ben Hoyt talks to Jim Lawless about his experience with various languages, including Go.
Stray Pointers: Discussing Programming Languages with Ben Hoyt
Go tip of the week: Value receivers and nil
Imagine a struct with two methods; one has a pointer receiver and the other has a value receiver.
package main
type S struct {
N int
}
func (s *S) PointerRcv() {
}
func (s S) ValueRcv() {
}
What happens if the receiver is nil
?
func main() {
var s *S // s is nil
s.PointerRcv()
s.ValueRcv()
}
Variable s
assumes the zero value of *S
, which is nil
. None of the two method accesses the receiver, so both method calls should go through without issues.
However, if you run this code, the call to s.ValueRcv()
panics!
What happens here?
Consider that methods are simply functions with some syntactic sugar. A method func (s S) f()
is semantically identical to the function func f(s S)
. The method receiver becomes the first argument of the function.
Thus, the above code can be written without methods as follows:
package main
type S struct {
N int
}
func PointerFunc(s *S) {
}
func ValueFunc(s S) {
}
func main() {
var s *S // s is nil
PointerFunc(s)
ValueFunc(*s)
}
Now it should be easy to see why ValueFunc()
panics. The pointer s
must be dereferenced when passing it to ValueFunc()
. Dereferencing a nil
pointer is not possible and results in a panic.
For the method func (s *S)PointerRcv()
, the receiver (or the function parameter in the second example) does not need to get dereferenced. Hence no panic occurs.
So if you have a type with pointer and value receivers, take care to not call any methods on a nil
value of that type.
Overheard on LinkedIn: I have a joke about UDP
I have a joke about UDP and I don't care if you get it.
– Shawn Plowman
I tried to come up with an IPv4 joke, but the good ones were all already exhausted.
– Nick B.
I wanted to share a joke about IPv6, but there are too many to choose from.
– Dinesh Gurnani
(Source: LinkedIn)
More articles, videos, talks
Scaling GraphQL Subscriptions in Go with Epoll and Event Driven Architecture - WunderGraph
While this post is primarily about a new feature of Wundergraph's product, it also shares valuable insights into using
pprof
for profiling goroutines and heap allocations.
Write Integration Tests For Mongo With Golang - Hasan Ocak Tech Blog
What's so special about MongoDB integration tests? Well, MongoDB, that is. Hasan Ocak shows how it's done.
Are compiler directives the new hot sh*t in code optimization? Victor Conner shares his experiences using the
//go:nosplit
directive during the Advent of Code for a measurable speedup.
Omitting dev dependencies in Go binaries | Redowan's Reflections
If you want to track binary dependencies (a.k.a. development tools) in a Go project, a tools.go file guarded by a build tag does the trick.
Stop stamping commit info in Go projects | Wilson Husin
If you use flags to stamp arbitrary version info into Go binaries, consider adding the exact commit revision using
debug.ReadBuildInfo()
, for higher accuracy and better build reproducibility.
In Go, I'm going to avoid using 'any' as an actual type
The empty interface, or
interface{}
never received much love. Now it's increasingly replaced by the aliasany
, which is easier on the eyes (but still has the same connotation of poking holes in type safety). Chris Siebenmann is not happy withany
as a general replacement forinterface{}
.
Projects
Libraries
Libraries that have been announced this week
GitHub - ionoscloudsdk/comptplus: cobra-prompt with flag completions
comptplus
enhances Cobra'scobra-prompt
library with flag completions and persistence, customizable flag reset behavior, and pre- and post-execution hooks.
Signals is for single processes what NATS or RabbitMQ are for distributed applications. Signals provides a process-internal event system if plain channels are too simple and other approaches are too complex.
GitHub - hossein1376/grape: Modern, zero-dependency HTTP library for Go
A convenience layer on top of the std library for building HTTP servers with
slog
logging and the upcoming, improved HTTP router (in Go v1.22).
Tools and applications
GitHub - rico-vz/SleepSageCLI: Optimal sleep calculator directly from your terminal ✨
Maybe not that useful for real life (as it doesn't track your sleep, but OTOH, that's the last thing I want my terminal to do!), but surely a nice showcase of writing interactive CLI apps with
charmbracelet/huh
andcharmbracelet/log
.
GitHub - rednafi/link-patrol: Detect dead links in markdown files
Ooh, that's the tool I need! This newsletter, as well as my blogs, start their life as Markdown files, and while it's hard to change a link in an already sent email, blog articles should at least be kept up-to-date with active links.
A 3D Multiplayer Pong! You can play against an AI if no human players are available. You wouldn't guess that this is a "My First Go Project" kind of application.
Completely unrelated to Go
TIL: In my shell, I can bind CTRL-r to fzf
and get an interactive, crazy fast fuzzy search through my command history while typing.
Which command did you run 1731 days ago? - by Thorsten Ball
•—•—•
One reason for loving Go is its support for writing clear code. But there is more to achieving and maintaining clarity in software.
The most important goal in designing software is understandability | nicole@web
Happy coding! ʕ◔ϖ◔ʔ
Questions or feedback? Drop me a line. I'd love to hear from you.
Best from Munich, Christoph
Not a subscriber yet?
If you read this newsletter issue online, or if someone forwarded the newsletter to you, subscribe for regular updates to get every new issue earlier than the online version, and more reliable than an occasional forwarding.
Find the subscription form at the end of this page.
How I can help
If you're looking for more useful content around Go, here are some ways I can help you become a better Gopher (or a Gopher at all):
On AppliedGo.net, I blog about Go projects, algorithms and data structures in Go, and other fun stuff.
Or visit the AppliedGo.com blog and learn about language specifics, Go updates, and programming-related stuff.
My AppliedGo YouTube channel hosts quick tip and crash course videos that help you get more productive and creative with Go.
Enroll in my Go course for developers that stands out for its intense use of animated graphics for explaining abstract concepts in an intuitive way. Numerous short and concise lectures allow you to schedule your learning flow as you like.
Christoph Berger IT Products and Services
Dachauer Straße 29
Bergkirchen
Germany