week 36, 2021

The hidden performance overhead of Python C extensions

Python is slow, and compiled languages like Rust, C, or C++ are fast. So when your application is too slow, rewriting some of your code in a compiled extension can seem like the natural approach to speeding things up.

Unfortunately, compiled extensions are sometimes actually slower than the equivalent Python code. And even when they’re faster, the performance improvement might be far less than you’d imagine, due to hidden overhead caused by two factors:

  1. Function call overhead.
  2. Serialization/deserialization overhead.

Let’s see where these hidden performance overheads comes from, and then see some solutions to get around them.

Source: The hidden performance overhead of Python C extensions, an article by Itamar Turner-Trauring.

I18n in Go: Managing Translations

Recently I've been building a fully internationalized (i18n) and localized (l10n) web application for the first time with Go's packages. I've found that the packages and tools that live under are really effective and well designed, although it's been a bit of a challenge to figure out how to put it all together in a real application.

In this tutorial I want to explain how you can use packages to manage translations in your application. Specifically:

  • How to use the and packages to print translated messages from your Go code.
  • How to use the gotext tool to automatically extract messages for translation from your code into JSON files.
  • How to use gotext to parse translated JSON files and create a catalog containing translated messages.
  • How to manage variables in messages and provided pluralized versions of translations.

Source: I18n in Go: Managing Translations, an article by Alex Edwards.

Quadratic algorithms are slow (and hashmaps are fast)

Hello! I was talking to a friend yesterday who was studying for a programming interview and trying to learn some algorithms basics.

The topic of quadratic-time vs linear-time algorithms came up, I thought this would be fun to write about here because avoiding quadratic-time algorithms isn’t just important in interviews – it’s sometimes good to know about in real life too! I’ll explain what a “quadratic-time algorithm is” in a minute :)

here are the 3 things we’ll talk about:

  1. quadratic time functions are WAY WAY WAY slower than linear time functions
  2. sometimes you can make a quadratic algorithm into a linear algorithm by using a hashmap
  3. this is because hashmaps lookups are very fast (instant!)

I’m going to try to keep the math jargon to a minimum and focus on real code examples and how fast/slow they are.

Source: Quadratic algorithms are slow (and hashmaps are fast), an article by Julia Evans.

Are Dockerfiles good enough?

Containers have quickly become the favorite way to deploy software, for a lot of good reasons. They have allowed, for the first time, developers to test "as close to production" as possible. Unlike say, VMs, containers have a minimal performance hit and overhead. Almost all of the new orchestration technology like Kubernetes relies on them and they are an open standard, with a diverse range of corporate rulers overseeing them. In terms of the sky-high view, containers have never been in a better place.

I would argue though that in our haste to adopt this new workflow, we missed some steps. To be clear, this is not to say containers are bad (they aren't) or that they aren't working correctly (they are working mostly as advertised). However many of the benefits to containers aren't being used by organizations correctly, resulting in a worse situation than before. While it is possible to use containers in a stable and easy-to-replicate workflow across a fleet of servers, most businesses don't.

Source: Are Dockerfiles good enough?, an article by Mathew Duggan.

An Introduction to Type Level Programming

In this article you’ll learn how to build programs that make heavy use of type-level programming by working through building a theming system. I originally developed the ideas behind this talk and article when trying to write something to unify the various themes and configurations for my own xmonad desktop setup, but the theming system you’ll build as you work through this article can be equally applied to theming web content, desktop or command line applications, or really anything that needs configurable theming.

Source: An Introduction to Type Level Programming, an article by Rebecca Skinner.

Ten Things I Look For In a Code Review

Feedback is critical in any engineering organization – and that feedback often comes through code reviews. Junior engineers learn how to manage complexity, simplify the logic, and to develop the codebase from senior engineers. But, on the other hand, even the most senior engineers benefit from having a second pair of eyes on their code.

Yet, very few organizations set standards around their code reviews. By using a checklist, you can increase code quality across the entire organization. Better yet, it serves as an excellent onboarding document to train new reviewers, expanding the pool of reviewers and expediting the review pipeline.

I've compiled a starting point of 10 questions to ask when reviewing code.

Source: Ten Things I Look For In a Code Review, an article by Matt Rickard.

Monads, part six: But, really, what is a monad?

In the first entry in this series, I argued that "what is a monad?" is not a useful question for the working programmer. In the rest of the series so far, I have explained how to recognize situations in which a monad could be useful, how to apply monads, and how to create bespoke ones.

But I still have not really defined what a monad is, and, while I stand by the argument that the answer is not useful, I can imagine that not having the answer may be a bit frustrating. In this post, I'll try to explain what a monad is, as best I can.

Source: Monads, part six: But, really, what is a monad?, an article by Gary Verhaegen.

Preventing Data Races Using Actors in Swift

Data races — the worst nightmare of all developers! They are hard to detect, very unpredictable, and extremely difficult to fix. Apple has given developers various toolsets such as NSLock and serial queues to prevent data races from happening during runtime, however, none of them are capable of catching race conditions during compile-time. With the release of Swift 5.5, this will no longer be the case!

Introducing Actor, the new Swift language feature that can help developers to catch any possible race conditions during development time. In this article, we will first look at how a data race occurs when using dispatch queues and asynchronous tasks. After that, we will look at how actors can help us to identify race conditions in our code and prevent them from happening once and for all!

Source: Preventing Data Races Using Actors in Swift, an article by Lee Kah Seng.

Awk: The Power and Promise of a 40-Year-Old Language

Languages don't enjoy long lives. Very few people still code with the legacies of the 1970s: ML, Pascal, Scheme, Smalltalk. (The C language is still widely used but in significantly updated versions.) Bucking that trend, the 1977 Unix utility Awk can boast of a loyal band of users and seems poised to continue far into the future. In this article, I’ll explain what makes Awk special and keeps it relevant.

Source: Awk: The Power and Promise of a 40-Year-Old Language, an article by Andy Oram.

Kubernetes CI/CD pipelines: What, why, and how

This blog can provide you with useful information on how to set up a Kubernetes CI/CD workflow using state-of-the-art of open source DevOps tools, whether you are:

  • A developer at the start of your journey with enterprise software
  • An experienced software engineer working on your company’s applications, or
  • An engineering lead trying to improve your team’s productivity

Source: Kubernetes CI/CD pipelines: What, why, and how, an article by Alex Chalkias.

Why you shouldn't parse the output of ls(1)

The ls(1) command is pretty good at showing you the attributes of a single file (at least in some cases), but when you ask it for a list of files, there's a huge problem: Unix allows almost any character in a filename, including whitespace, newlines, commas, pipe symbols, and pretty much anything else you'd ever try to use as a delimiter except NUL. There are proposals to try and "fix" this within POSIX, but they won't help in dealing with the current situation (see also how to deal with filenames correctly). In its default mode, if standard output isn't a terminal, ls separates filenames with newlines. This is fine until you have a file with a newline in its name. And since I don't know of any implementation of ls that allows you to terminate filenames with NUL characters instead of newlines, this leaves us unable to get a list of filenames safely with ls.

Source: Why you shouldn't parse the output of ls(1).

The Broken Eye

As the old gods awaken and satrapies splinter, the Chromeria races to find the only man who can still end a civil war before it engulfs the known world. But Gavin Guile has been captured by an old enemy and enslaved on a pirate galley. Worse still, Gavin has lost more than his powers as Prism -- he can't use magic at all.

Without the protection of his father, Kip Guile will face a master of shadows as his grandfather moves to choose a new Prism and put himself in power. With Teia and Karris, Kip will have to use all his wits to survive a secret war between noble houses, religious factions, rebels, and an ascendant order of hidden assassins called The Broken Eye.

In the evening I started in The Broken Eye, Lightbringer Book 3 by Brent Weeks. I enjoyed the previous books a lot, especially the second one.