cost of enum-to-string: C++26 reflection vs the old ways

Two months ago I published “the hidden compile-time cost of C++26 reflection”, where I measured what including <meta> and doing some basic reflection actually costs per translation unit. If you haven’t read it, start there – this post builds directly on top of it.

That article used a prerelease GCC 16 snapshot. Since then, GCC 16 has been officially released1 and is now widely available, which seemed like a good excuse to revisit the topic with a more realistic example: enum-to-string conversion.

Enum-to-string is the “hello world” of reflection – but it’s also genuinely useful in real projects, for things like logging, serialization, debugging, and so on. If you adopt reflection in a real codebase, it might be the first thing you’ll write.

... read more

stackless coroutines for gamedev in ~200 lines of C++

C++20 coroutines have lovely1 syntax. They are also a terrible fit for game development.2

If you’ve ever tried to use them for boss scripts, dialogue, or AI behaviors – anywhere you want straight-line code that pauses for a few frames – you’ve probably hit the same wall I did: opaque handles, heap allocations3, hidden compiler lowering, and – most damning for games – no way to serialize a paused coroutine to disk.

In this article, I will present sfex::Coroutine: a ~200-line stackless macro-based coroutine library built around a variant of the classic switch + __LINE__ trick. Like my previously discussed sfex::Profiler, these coroutines are meant to be simple and lightweight.

... read more

the hidden compile-time cost of C++26 reflection

I am very excited about C++26 reflection.

I am also obsessed by having my code compile as quickly as possible. Fast compilation times are extremely valuable to keep iteration times low, productivity and motivation high, and to quickly see the impact of your changes. 1

With time and experience, I’ve realized that C++ can be an extremely fast-to-compile language. Language features like templates are not the issue – the Standard Library is.

... read more

building a lightweight ImGui profiler in ~500 lines of C++

Performance profiling is essential for game development and real-time applications.

While powerful tools like Tracy or VTune can do the job very well, they often come with unnecessary complexity, integration annoyances, or platform-specific limitations.

What if you just need a dead simple, lightweight, minimal-overhead hierarchical profiler that seamlessly integrates with Dear ImGui? That’s exactly what I built for my CppCon 2025 keynote demo, and this article will explore its design and implementation.

... read more

how to break or continue from a lambda loop?

Here’s an encapsulation challenge that I frequently run into: how to let users iterate over an internal data structure without leaking implementation details, but still giving them full control over the loop?

Implementing a custom iterator type requires significant boilerplate and/or complexity, depending on the underlying data structure.

Coroutines are simple and elegant, but the codegen is atrocious – definitely unsuitable for hot paths.

... read more

free performance: autobatching in my SFML fork

In one of my previous articles, I discussed the design and implementation of the batching system in my fork of SFML.

That system works well, but it requires users to manually create a batch, add drawables to it, and then draw the batch onto a render target. While effective, this manual approach begs the question:

Wouldn’t it be nice if drawables were automatically batched, whenever possible?

... read more

AoS vs SoA in practice: particle simulation

I recently released BubbleByte on Steam, my second commercial game built with my fork of SFML.

It’s an incremental/clicker/idle game where – eventually – the player will see thousands upon thousands of particles on screen simultaneously.

Even with a basic AoS (Array of Structures) layout, the game’s performance is great thanks to the draw batching system. However, I began wondering how much performance I might be leaving on the table by not adopting a SoA (Structure of Arrays) layout. Let’s figure that out in this article!

... read more