Elixir string operations seem slow
...and why it's a good thing
I personally hate it when people post clickbait titles and take their sweet time getting to the point, so let’s do this first:
TL;DR: Some Elixir string operations, most notably String.at/2
work in linear time,
as opposed to constant time, like the intuition might suggest. This is because the String
module is UTF-8 aware.
UTF-8 encodes characters outside of ASCII with more than one byte, so in order to find the n-th character in a string you need to process it from the beginning, you can’t just use an offset in memory.
In this blogpost I go a bit more in depth about how UTF-8 works and compare some approaches to getting performant results, so even if you knew the tl;dr you might find something interesting here regardless.
Context
I as doing an algorithmic exercise containing string manipulation in Elixir and saw that even though my approach was correct and seemed pretty optimal, it was timing out on larger inputs - and timing out by a lot. After looking into it a bit I realised
Notion Buttons
...and what they need to be truly useful
I’m a long time power-user of Notion. For the last couple of years I’ve been using it for all of my note-taking, work organisation and tracking, online documentation, storing cooking recipes and much more. Recently they introduced a new Buttons feature and it excited many people who thought it would be the missing piece in their workflow organisation.
I played around with it for a while and I can see the current functionality is a great starting point, but it needs a bit more to actually be useful (to me)
How to use data spanning multiple data sources in Elixir
Unleashing the power of the Ecto preload functions
Below is a reprint of the article I wrote for the Rekki Medium page.
REKKI builds tools that help people along the restaurant supply chain do their jobs better.
We have a free mobile app that lets restaurants order and chat with suppliers, and a web-based tool for suppliers that helps them process orders, manage product codes and catalogues, and communicate more easily with their customers. The majority of REKKI’s backend is written in Elixir, working hand in hand with services written in Go and Node. The Elixir services handle most of what the user sees in the app like the real-time communication with the supplier and the status of the orders.
We use Ecto to talk to our databases, which is the de facto standard. It provides a nice, composable data querying and manipulation DSL and an ORM-like way to map information stored in the database to Elixir structs using Schemas. In this post, we’re going to focus on advanced usage of one of its features: “preloading” of the related data.
If you’re already an Ecto power user and know how we usually use preloads, you might want to skip ahead to the “Non-trivial scenario,” or straight to the “Using preload functions” section.
setting the scene
Let’s say we’re building a blogging platform, a bit like Medium, where users can write posts and comments. We’d probably model posts and comments as separate tables in a relational db, where each comment belongs to a post, a post can have multiple comments, and both posts and comments belong to individual users.
In that scenario, if we wanted to load all comments written by a certain user, we’d write something like this: