{"id":19922420,"url":"https://github.com/yuyuzha0/fast-printf","last_synced_at":"2026-01-26T05:02:20.000Z","repository":{"id":173575760,"uuid":"646713425","full_name":"YuyuZha0/fast-printf","owner":"YuyuZha0","description":"A precompiled printf spec compatible string formatting library for java","archived":false,"fork":false,"pushed_at":"2026-01-22T07:37:30.000Z","size":445,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-22T22:22:38.622Z","etag":null,"topics":["fast","format","high-performance","java","logprocess","printf","printf-functions"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/YuyuZha0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-05-29T07:08:03.000Z","updated_at":"2026-01-22T18:45:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"9c9413ef-a12c-4f53-8a31-d20b790570da","html_url":"https://github.com/YuyuZha0/fast-printf","commit_stats":null,"previous_names":["yuyuzha0/fast-printf"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/YuyuZha0/fast-printf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YuyuZha0%2Ffast-printf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YuyuZha0%2Ffast-printf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YuyuZha0%2Ffast-printf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YuyuZha0%2Ffast-printf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YuyuZha0","download_url":"https://codeload.github.com/YuyuZha0/fast-printf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YuyuZha0%2Ffast-printf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28767013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T03:54:34.369Z","status":"ssl_error","status_checked_at":"2026-01-26T03:54:33.031Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fast","format","high-performance","java","logprocess","printf","printf-functions"],"created_at":"2024-11-12T22:10:55.884Z","updated_at":"2026-01-26T05:02:19.993Z","avatar_url":"https://github.com/YuyuZha0.png","language":"Java","readme":"# fast-printf\n\n[![Java CI](https://github.com/YuyuZha0/fast-printf/actions/workflows/maven.yml/badge.svg)](https://github.com/YuyuZha0/fast-printf/actions/workflows/maven.yml)\n[![codecov](https://codecov.io/github/YuyuZha0/fast-printf/graph/badge.svg?token=UPPTCS4DRS)](https://codecov.io/github/YuyuZha0/fast-printf)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.yuyuzha0/fast-printf.svg?style=flat-square)](https://search.maven.org/artifact/io.github.yuyuzha0/fast-printf)\n[![License](https://img.shields.io/badge/License-GPL--2.0--with--classpath--exception-blue.svg?style=flat-square)](https://openjdk.java.net/legal/gplv2+ce.html)\n\nA high-performance, `glibc`-compliant, and low-allocation `printf`-style formatter for Java 8+.\n\n`fast-printf` is a specialized formatting library designed for performance-critical applications where standard\nutilities like `String.format()` become a bottleneck. It achieves significant speedups through a **compile-once,\nrun-many** approach and a sophisticated architecture that minimizes memory allocations and garbage collection pressure.\n\n## Key Features\n\n* 🚀 **High Performance**: Consistently outperforms `String.format()` across all Java versions. The advantage is most\n  significant on older runtimes (up to **4x faster** on JDK 8), and remains substantial even on modern runtimes (~**3x\n  faster** on JDK 21).\n* 🗑️ **Low Allocation**: Employs a rope-like character sequence data structure for internal string building. This avoids\n  creating intermediate strings and character arrays, dramatically reducing GC pressure in hot loops.\n* ⚙️ **Glibc Compatible**: Adheres to the widely-used `glibc` `printf` conventions (from C/C++), providing familiar and\n  predictable behavior rather than following the `java.util.Formatter` specification.\n* 💡 **State-of-the-Art Float Formatting**: **Backports the high-fidelity floating-point formatting engine from OpenJDK\n  21.** This brings the modern \"Schubfach\" algorithm to Java 8+, ensuring correctly rounded and the shortest possible\n  output for `double` and `float` values—a level of accuracy not available in older JDKs' `String.format()`.\n* ⛓️ **Fluent, No-Boxing API**: Provides a fluent builder (`Args.create().putInt(...)`) that accepts primitive arguments\n  without any boxing overhead, maximizing performance in critical code paths.\n* 🧩 **Zero Dependencies**: A lightweight library with no external dependencies.\n* ☕ **Java 8+**: Compatible with all modern Java runtimes.\n\n## Performance (JDK 21)\n\nWhile `fast-printf` provides a significant speedup on all platforms, it's important to understand how the landscape is\nchanging. The following benchmarks were run on **JDK 21**, where `String.format()` has received substantial\noptimizations.\n\nThe benchmark uses a complex format string (`%#018x|%-15.7g|%S|%c|%d|%15.5f`) to stress the formatting logic over simple\nstring concatenation.\n\n| Benchmark (`avgt`, ns/op)               | Score    | Notes                                                     |\n|-----------------------------------------|----------|-----------------------------------------------------------|\n| **`fastPrintf` (varargs)**              | **~394** | The core library performance with auto-boxing.            |\n| `fastPrintf` (with `ThreadLocal` cache) | ~466     | Opt-in cache; can have higher overhead for short strings. |\n| `jdkPrintf` (`String.format`)           | ~1218    | The baseline for comparison on a modern JDK.              |\n\n*Lower scores are better. Source: `ComplexFormatBenchmark`.*\n\n### Performance on Older JDKs\n\nThe performance advantage of `fast-printf` is even more pronounced on older runtimes like **Java 8 or 11**, where\n`String.format()` is less optimized. On these versions, speedups of **up to 4x** are common for complex formats.\n\nAcross all versions, the primary advantage of `fast-printf` remains its **dramatically lower memory allocation**, which\nleads to reduced GC pressure in high-throughput applications.\n\n## When to use `fast-printf`\n\nThis library is ideal for performance-sensitive applications:\n\n* **High-throughput logging**: Formatting log messages in tight, performance-critical loops.\n* **Data Serialization**: Generating text-based data formats (e.g., CSV, protocol messages) at high speed.\n* **Real-time systems**: Financial applications, game engines, or monitoring agents where GC pauses must be minimized.\n* Anywhere `String.format()` has been identified as a performance bottleneck.\n\nFor general-purpose string formatting where performance is not the primary concern, the standard `String.format()` is\noften sufficient.\n\n## Installation\n\n### Maven\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.yuyuzha0\u003c/groupId\u003e\n    \u003cartifactId\u003efast-printf\u003c/artifactId\u003e\n    \u003cversion\u003e1.2.11\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\n```groovy\nimplementation 'io.github.yuyuzha0:fast-printf:1.2.11'\n```\n\n## Usage\n\nThe core idea is to compile a format string once into a `FastPrintf` instance and reuse it for all subsequent formatting\noperations.\n\n```java\nimport io.fastprintf.Args;\nimport io.fastprintf.FastPrintf;\n\nimport java.time.LocalDateTime;\n\npublic class Example {\n    // Compile once and reuse. The FastPrintf instance is immutable and thread-safe.\n    private static final FastPrintf FORMATTER = FastPrintf.compile(\n            \"ID: %#08X, Score: %05.2f, User: %.5S, Time: %t{yyyy-MM-dd HH:mm:ss}\"\n    );\n\n    public static void main(String[] args) {\n        LocalDateTime now = LocalDateTime.now();\n\n        // 1. Using varargs - Simple and convenient\n        String result1 = FORMATTER.format(255, Math.PI, \"test-user\", now);\n        System.out.println(result1);\n        // Output: ID: 0X0000FF, Score: 03.14, User: TEST-, Time: 2023-10-27 10:30:00\n\n        // 2. Using the fluent Args builder - Maximum performance, no boxing\n        Args args = Args.create()\n                .putInt(255)\n                .putDouble(Math.PI)\n                .putString(\"test-user\")\n                .putDateTime(now);\n        String result2 = FORMATTER.format(args);\n        System.out.println(result2);\n        // Output: ID: 0X0000FF, Score: 03.14, User: TEST-, Time: 2023-10-27 10:30:00\n    }\n}\n```\n\n### Convenience vs. Maximum Performance\n\n`fast-printf` offers two ways to provide arguments, each with a specific purpose:\n\n* **Convenience:** `FORMATTER.format(123, \"test\")` or `Args.of(123, \"test\")`.\n    * This is the easiest and most readable method.\n    * It uses varargs (`Object...`), which involves **auto-boxing** primitive types (e.g., `int` becomes `Integer`).\n      This is fine for most use cases.\n\n* **Maximum Performance:** `Args.create().putInt(123).putString(\"test\")`.\n    * This fluent builder API is designed for performance-critical code.\n    * Methods like `putInt(int)` and `putDouble(double)` accept unboxed primitives, **avoiding all allocation and boxing\n      overhead** for those arguments. Use this style inside hot loops.\n\n## Advanced: JDK 21 Floating-Point Formatting on Java 8\n\nOne of the key features of `fast-printf` is its superior floating-point formatting, which provides correctness and\nperformance guarantees unavailable in standard Java 8.\n\n### The Problem\n\nThe `String.format()` implementation in older JDKs (prior to JDK 18) had known issues with floating-point-to-decimal\nconversion. It could produce results that were not the shortest, correctly-rounded representation, leading to subtle\naccuracy bugs, especially in scientific and financial applications.\n\n### The Solution\n\n`fast-printf` directly **backports the modern floating-point formatting engine from OpenJDK 21**. This engine is based\non the advanced \"Schubfach\" algorithm, which guarantees the shortest, most accurate decimal representation of a binary\nfloating-point number.\n\nBy including this modern implementation, `fast-printf` ensures that your floating-point numbers are formatted with\nstate-of-the-art precision and correctness, even when your application is running on Java 8.\n\n## How It Works: Under the Hood\n\nThe performance of `fast-printf` comes from four key architectural pillars:\n\n1. **Ahead-of-Time Compiler**: `FastPrintf.compile()` parses the format string into a series of `Appender` objects—a\n   list of optimized formatting steps. This work is done only once.\n2. **Zero-Copy String Building**: The library uses an internal, rope-like `Seq` data structure. When concatenating\n   formatted parts, it creates lightweight wrapper objects instead of copying characters. The final `String` is rendered\n   in a single, efficient pass at the very end.\n3. **Ahead-of-Time Argument Processing**: The `Args` object converts your arguments into a list of `FormatTraits`\n   —specialized, type-aware handlers. This eliminates `instanceof` checks and reflection from the critical formatting\n   loop.\n4. **Backported Formatting Logic**: As mentioned above, it incorporates the modern, high-performance `DoubleToDecimal`\n   logic from OpenJDK 21 to ensure float/double formatting is both fast and mathematically correct on all supported Java\n   versions.\n\n## API Reference\n\nThe format string syntax is:\n`%[flags][width][.precision]specifier[{date-time-pattern}]`\n\n---\n\n### Custom Date/Time Formatting\n\nA powerful extension is the ability to provide an inline `DateTimeFormatter` pattern for the `%t` and `%T` specifiers.\n\n* **Syntax**: `%t{pattern}`\n* **Example**: `%t{yyyy-MM-dd'T'HH:mm:ss.SSSZ}`\n* **Default**: If no pattern is provided (`%t`), an appropriate ISO formatter is chosen based on the argument type (\n  e.g., `ISO_OFFSET_DATE_TIME` for a `ZonedDateTime`).\n\n---\n\n### Specifiers\n\n| Specifier  | Output                                                                                  | Example                      |\n|:----------:|-----------------------------------------------------------------------------------------|------------------------------|\n| `d` or `i` | Signed decimal integer                                                                  | `392`                        |\n|    `u`     | Unsigned decimal integer                                                                | `7235`                       |\n|    `o`     | Unsigned octal                                                                          | `610`                        |\n|    `x`     | Unsigned hexadecimal integer (lowercase)                                                | `7fa`                        |\n|    `X`     | Unsigned hexadecimal integer (uppercase)                                                | `7FA`                        |\n| `f` / `F`  | Decimal floating point                                                                  | `392.65`                     |\n|    `e`     | Scientific notation (lowercase `e`)                                                     | `3.9265e+2`                  |\n|    `E`     | Scientific notation (uppercase `E`)                                                     | `3.9265E+2`                  |\n| `g` / `G`  | Shortest representation of `%e` or `%f`                                                 | `392.65`                     |\n| `a` / `A`  | Hexadecimal floating point (lowercase/uppercase `p`)                                    | `-0xc.90fep-2`               |\n|    `c`     | Character                                                                               | `a`                          |\n|    `s`     | String of characters (from `Object.toString()`)                                         | `sample`                     |\n|    `S`     | String of characters, **converted to uppercase**                                        | `SAMPLE`                     |\n| `t` / `T`  | Date/Time string (case affects final string output)                                     | `2023-12-31T23:59:59+01:00`  |\n|    `p`     | Object \"pointer\" (class name + identity hash). Throws an exception for primitive types. | `java.lang.Integer@707f7052` |\n|    `n`     | Nothing printed. The argument is consumed.                                              |                              |\n|    `%`     | A literal `%` character                                                                 | `%`                          |\n\n---\n\n### Flags\n\n|    Flag     | Description                                                                                                                                                                                                               |\n|:-----------:|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n|     `-`     | Left-aligns the result within the field width.                                                                                                                                                                            |\n|     `+`     | Forces the result to be prefixed with a sign (`+` or `-`), even for positive numbers. Overrides the space flag.                                                                                                           |\n| ` ` (space) | Prefixes positive numbers with a space. Ignored if the `+` flag is present.                                                                                                                                               |\n|     `#`     | Alternate form: \u003cul\u003e\u003cli\u003eFor `o`, prefixes with `0`.\u003c/li\u003e\u003cli\u003eFor `x`/`X`, prefixes with `0x`/`0X`.\u003c/li\u003e\u003cli\u003eFor `f`, `e`, `g`, forces a decimal point.\u003c/li\u003e\u003cli\u003eFor `g`/`G`, prevents stripping of trailing zeros.\u003c/li\u003e\u003c/ul\u003e |\n|     `0`     | Pads the output with leading zeros (instead of spaces) to meet the specified width. Ignored if `-` is present or if precision is specified for an integer.                                                                |\n\n---\n\n### Width and Precision\n\n| Field        | Description                                                                                                                                                                                                                                                                                                 |\n|:-------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `width`      | Minimum characters to print. Padded with spaces (or zeros with `0` flag). Never truncates. `*` reads width from the next `int` argument.                                                                                                                                                                    |\n| `.precision` | \u003cul\u003e\u003cli\u003e**Integers:** Minimum number of digits (zero-padded).\u003c/li\u003e\u003cli\u003e**Floats (`f`, `e`):** Digits after the decimal point.\u003c/li\u003e\u003cli\u003e**Floats (`g`):** Max significant digits.\u003c/li\u003e\u003cli\u003e**String (`s`, `S`):** Max characters to print.\u003c/li\u003e\u003cli\u003e`.*` reads precision from the next `int` argument.\u003c/li\u003e\u003c/ul\u003e |\n\n## Key Differences from `String.format()`\n\n`fast-printf` intentionally differs from Java's `String.format` to align with `glibc` conventions and maximize\nperformance:\n\n* **Glibc vs. Java `Formatter` Conventions**: Follows `glibc` `printf`. For example, `%S` converts the entire string to\n  uppercase, unlike Java's behavior which is tied to `Formattable`.\n* **`%p` (Pointer) Specifier**: Provides the C-style `%p` specifier to print an object's identity. This useful specifier\n  is **not available** in Java's `String.format()`. The implementation is also type-safe and will correctly throw an\n  exception if given a primitive type, preventing bugs related to auto-boxing.\n* **No Argument Indexing**: Features like `%2$s` are not supported. Arguments are always consumed sequentially for\n  maximum performance.\n* **No Locale Support**: Formatting is locale-agnostic for performance (`.` is always the decimal separator).\n\n## License\n\n`fast-printf` is licensed under the **GNU General Public License v2 with Classpath Exception**, the same license used by\nthe OpenJDK.\n\nThis choice of license is deliberate, as this library includes internal utility classes that are derivative works of\nOpenJDK (specifically for high-fidelity floating-point formatting). These backported files retain their original\ncopyright headers and are governed by the terms of the GPLv2+CE, and thus the library as a whole adopts this license.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuyuzha0%2Ffast-printf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuyuzha0%2Ffast-printf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuyuzha0%2Ffast-printf/lists"}