Converting an Integer to a Decimal String in Under Two Nanoseconds

Researchers have developed a SIMD-based algorithm that accelerates integer-to-decimal string conversion by 2-4x compared to the C++ standard library. This new method leverages AVX-512 instructions on modern Intel and AMD processors, completely eliminating traditional lookup tables.
ABSTRACT
Objective
Converting binary integers to variable-length decimal strings is a fundamental operation in computing. Conventional fast approaches rely on recursive division and small lookup tables. The goal of this work is to develop a significantly faster method for this task.
Methods
We propose a SIMD-based algorithm that leverages integer multiply-add instructions available on recent AMD and Intel processors. Our method eliminates lookup tables entirely and computes multiple quotients and remainders in parallel. Additionally, we introduce a dual-variant design with dynamic selection that adapts to input characteristics: a branch-heavy variant optimized for homogeneous digit-length distributions and a branch-light variant for heterogeneous datasets.
Results
Our single-core algorithm consistently outperforms all competing methods across the full range of integer sizes. It runs 1.4–2× faster than the closest competitor and 2–4× faster than the C++ standard library function ‘std::to_chars’ across tested workloads.
Conclusion
The proposed SIMD-based approach with dual-variant dynamic selection provides a substantial performance improvement for integer-to-decimal conversion, delivering superior speed without relying on traditional lookup tables.
1 Introduction
Converting binary integers into their decimal string representations is a fundamental operation in software systems. It appears in virtually all applications—whether for displaying values in command line or graphical user interfaces, writing diagnostic logs, or serializing data to text-based formats such as JSON, XML, or CSV. Despite its ubiquity, this conversion task has received relatively little attention in the formal peer-reviewed literature, and common implementations may leave room for performance improvements. As data formats and logging systems become performance bottlenecks in modern applications, improving integer-to-string conversion speed directly benefits real-world software such as database engines, serialization libraries, and logging frameworks.
Modern processors provide several architectural features that could potentially be exploited to improve the performance of such conversions. SIMD (Single Instruction, Multiple Data) extensions, for example, allow the same arithmetic operation to be applied to multiple data elements in parallel. On recent x86-64 processors from Intel and AMD, the AVX-512 instruction sets can process 512-bit registers using single instructions, offering potential for accelerating numerical workloads. At the same time, processors can execute multiple independent instructions simultaneously (instruction-level parallelism) including load and store operations. To improve such parallelism, contemporary out-of-order execution engines can reorder instructions and use speculative execution to hide latencies and improve throughput. However, speculative execution might suffer from branch mispredictions. While branch predictors have become increasingly sophisticated, mispredicted branches still introduce performance penalties. These architectural factors interact in subtle ways when implementing high-performance integer-to-string conversions. Achieving both low latency and high throughput requires careful coordination between algorithmic structure and processor microarchitecture, including vector width utilization, instruction scheduling, and branch prediction behavior.
Our primary contribution is a new integer-to-string conversion algorithm that explicitly leverages SIMD parallelism. Our design exploits the AVX-512 instruction set to process multiple digits concurrently, computing quotients and remainders in parallel without costly integer divisions. Furthermore, a distinctive feature of our approach is its dual-variant mechanism, which dynamically selects between two specialized conversion paths based on sampled input characteristics: a branch-heavy variant optimized for homogeneous digit-length distributions and a branch-light variant for heterogeneous datasets. This adaptive design balances branch prediction accuracy with instruction-level parallelism.
As a secondary contribution, we present, to the best of our knowledge, the first formal empirical study of integer-to-string conversion performance on a modern AVX-512-capable processor. Our evaluation combines both randomized datasets—with controllable digit-length distributions—and data extracted from real-world files. In particular, we analyze how the distribution of digit lengths within the input affects throughput, revealing that this factor alone dominates overall performance. We compare our approach against widely used library implementations, and our results highlight where each variant excels and how architectural features influence observed performance.
The remainder of this paper is organized as follows. Section 2 reviews previous work and commonly used algorithms, including those found in standard libraries. Section 3 provides a brief overview of SIMD instructions and the AVX-512 extension relevant to our algorithm. Section 4 presents the mathematical foundation for our approach. Section 5 describes the design of our proposed algorithm, with emphasis on its SIMD data layout, parallel digit extraction, and dynamic variant-selection mechanism. Section 6 describes the benchmarking methodology, hardware platform, and performance metrics. Finally, Section 7 discusses the implications of our results and outlines possible extensions.
2 Related Work
Formally, the problem consists of converting an integer k, where ‘0’ is a shorthand for the code point value 48. In the general case, and ignoring negative values, we seek a sequence of characters. In practice, most algorithms first check whether the number is negative to handle the sign, and then proceed with the absolute value.
2.1 Naive and Baseline Methods
The classic approach repeatedly divides and takes the modulus by 10 to extract digits from least to most significant. Because digits are produced in reverse order, a final reversal step is required. Some variants instead write the number right-to-left into a buffer and then copy the resulting string to its correct position. More advanced implementations precompute the number of digits beforehand to place each character directly at its final position, avoiding both reversal and data movement, thereby enabling a single-pass implementation.
2.2 Two-Digit Lookup Methods
A common optimization is to reduce the number of division and modulus operations. Instead of extracting one digit per iteration, pairs of digits are produced by dividing by 100 and mapping the result (0–99) through a small lookup table of two-character strings. The final odd digit, if any, is handled separately. This strategy was popularized by Alexandrescu and adopted in several high-performance formatting libraries, such as fmt. It removes many divisions and relies on cache-friendly, sequential memory accesses, which are efficiently handled by modern CPUs.
2.3 Division by Constants
The conversion of integers to decimal digits often involves divisions by 10 or powers of two. Division instructions on mainstream computers are typically slower than multiplications. For this reason, optimizing compilers replace divisions by multiplicative divisions: a multiplication followed by a shift. The algorithm used by optimizing compilers usually follows Warren's approach. We can concisely summarize the mathematical results with optimal bounds.
2.4 Large-Chunk Precomputed Methods
The same idea can be extended to larger digit groups, most notably 4-digit and 5-digit blocks. However, table size grows exponentially with block width (40 KB for a 4-digit table), often exceeding the L1 data cache. Consequently, such approaches can be counterproductive due to cache misses.
Source: Hacker News


















