Two Thumb Rules for Efficient Code

2025-05-17

This article presents two practical tips for improving code efficiency: moving `if` conditions upwards and `for` loops downwards. Moving `if` conditions to the caller function reduces branching, simplifies control flow, and improves readability. Moving `for` loops to where batch data is processed leverages batch processing advantages, improves performance, and potentially unlocks vectorization. These two tips complement each other, effectively enhancing code efficiency, especially when handling large amounts of data.

Read more
Development

Beyond Scalar Select: Batching Event Streams for Efficiency

2025-05-15

The author describes the inefficiency of the scalar select anti-pattern in stateful service design, exemplified by an LSP server. Processing events one at a time leads to delays and resource waste. The proposed solution is to batch process event streams. A `batch_stream` function merges incoming events into batches, significantly improving efficiency. Under low load, it behaves like single-event processing, but under high load, it dramatically reduces overhead, boosting performance.

Read more
Development

Zig's Comptime: Powerful Yet Restrained Metaprogramming

2025-04-20

Zig's comptime feature is renowned for its capabilities: generics, conditional compilation, and more. However, it's deliberately restrictive, disallowing dynamic code generation, custom syntax extensions, runtime type information (RTTI), and I/O. This article explores the reasoning behind these limitations, showcasing how Zig achieves efficient and understandable metaprogramming through partial evaluation and type specialization. A custom printing function example demonstrates how Zig performs type-safe runtime reflection without RTTI. The article concludes by praising Zig's unique elegance in metaprogramming; while less powerful than alternatives, it's remarkably efficient and easy to use in practice.

Read more

Debugger as REPL: IntelliJ IDEA's Run to Cursor and Quick Evaluate Expression

2025-03-28

Tired of traditional debuggers, especially gdb and lldb's limitations with native code, the author discovered a powerful workflow in IntelliJ IDEA. Combining "Run to Cursor" and "Quick Evaluate Expression" transforms the debugger into a REPL. "Run to Cursor" executes the program to the cursor's position, while "Quick Evaluate Expression" lets you evaluate expressions (even newly typed code!) within the current stack frame. This approach replaces the line-by-line stepping with a more experimental, two-dimensional interaction within the editor, leveraging code completion and offering a significantly more efficient debugging experience.

Read more
Development

Favor Long Options in Scripts

2025-03-22

Many command-line utilities offer both short (-f) and long (--force) options. While short options are convenient for interactive use, long options are far superior in scripts. Their improved readability and self-explanatory nature enhance maintainability and understanding. For instance, in Git, `git switch --create release-{today} origin/main` is significantly clearer than `git switch -c my-new-branch`, particularly within complex scripts.

Read more
Development long options

Hardcore Rust: A Ray Tracer Without Dynamic Memory Allocation

2025-01-30

This post details a case study of writing a Rust application using only a minimal, artificially constrained API (no dynamic memory allocation). The author critiques RAII (Resource Acquisition Is Initialization) for leading to messy resource management and proposes a "hard mode": splitting the program into a `std` binary and a `#![no_std] no_alloc` library, allowing only the binary to directly request resources from the OS. Using a toy ray tracer as an example, the author meticulously explains handling pixel buffers, parallelization, the memory allocator, and scene parsing in this "hard mode," ultimately achieving a ray tracer without dynamic memory allocation.

Read more
Development

Invariants: A Powerful Tool for Writing Correct Code

2025-01-12

This article explores the concept of 'invariants' in programming and their applications. Starting with a small example—writing a binary search variation that computes the insertion point—the author demonstrates how defining and maintaining invariants leads to correct code. Invariants, the article explains, are properties that hold true throughout a system's dynamic evolution, simplifying reasoning by avoiding the complexities of considering numerous execution paths. Examples from projects like Cargo, rust-analyzer, and TigerBeetle illustrate the benefits of using invariants in large systems, such as improved maintainability and performance. The author concludes by summarizing the importance of invariants in both small-scale and large-scale programming, highlighting their value in writing correct and efficient code.

Read more

Revolutionary Idea: Applying Magit Principles to the jj Version Control System

2024-12-13

The author proposes a novel approach: applying the Magit version control interface from Emacs (which uses text files as its UI) to the nascent jj version control ecosystem. The article points out that Magit's text-based UI offers efficiency and portability. By leveraging the LSP protocol, a Magit-like experience can be implemented in various editors, avoiding redundant development. The author envisions generating specific text files (such as .jj/status.jj) and utilizing LSP features like semantic tokens, folding ranges, and goto definition to achieve Magit-like version control operations. The ultimate goal is to create a cross-platform, efficient user interface for jj version control.

Read more
Development