{"id":42029146,"url":"https://github.com/fmtlib/dtoa-benchmark","last_synced_at":"2026-01-26T04:30:37.433Z","repository":{"id":43728338,"uuid":"177339972","full_name":"fmtlib/dtoa-benchmark","owner":"fmtlib","description":"C++ double-to-string conversion benchmark","archived":false,"fork":false,"pushed_at":"2026-01-22T02:04:05.000Z","size":1884,"stargazers_count":26,"open_issues_count":0,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-22T03:34:34.327Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"miloyip/dtoa-benchmark","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fmtlib.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":"2019-03-23T21:04:45.000Z","updated_at":"2026-01-22T02:04:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fmtlib/dtoa-benchmark","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fmtlib/dtoa-benchmark","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmtlib%2Fdtoa-benchmark","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmtlib%2Fdtoa-benchmark/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmtlib%2Fdtoa-benchmark/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmtlib%2Fdtoa-benchmark/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fmtlib","download_url":"https://codeload.github.com/fmtlib/dtoa-benchmark/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fmtlib%2Fdtoa-benchmark/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28766886,"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":[],"created_at":"2026-01-26T04:30:35.998Z","updated_at":"2026-01-26T04:30:37.420Z","avatar_url":"https://github.com/fmtlib.png","language":"C++","readme":"# dtoa benchmark\n\nThis project is a complete rewrite of Milo Yip’s\n[dtoa-benchmark](https://github.com/miloyip/dtoa-benchmark), featuring an\nupdated set of algorithms that reflect the current state of the art and a\nsimplified workflow.\n\n## Introduction\n\nThis benchmark evaluates the performance of converting double-precision\nIEEE-754 floating-point values (`double`) to ASCII strings. The function\nsignature is:\n\n```cpp\nvoid dtoa(double value, char* buffer);\n```\n\nThe resulting string **must** be round-trip convertible: it should parse back\nto the original value **exactly** via a correct implementation of `strtod`.\n\nNote: `dtoa` is *not* a standard C or C++ function.\n\n## Procedure\n\nThe benchmark consists of two phases:\n\n1. **Correctness verification**  \n   All implementations are first validated to ensure round-trip correctness.\n\n2. **Performance measurement**\n\n   The benchmark case is:\n\n   * **RandomDigit**  \n     * Generate 100,000 random `double` values (excluding `±inf` and `NaN`).\n     * Reduce precision to 1–17 decimal digits in the significand.\n     * Convert each value to an ASCII string.\n\n   Each digit group is executed 10 times.  \n   For each configuration, 10 trials are run and the **minimum** elapsed time\n   is recorded.\n\n## Build and Run\n\n```bash\ncmake .\nmake run-benchmark\n```\n\nResults are written in CSV format to:\n\n```\nresults/\u003ccpu\u003e_\u003cos\u003e_\u003ccompiler\u003e_\u003ccommit\u003e.csv\n```\n\nThey are also automatically converted to HTML with the same base name.\n\n## Results\n\nThe following results were measured on a **MacBook Pro (Apple M1 Pro)** using:\n\n* Compiler: Apple clang 17.0.0 (clang-1700.0.13.5)\n* OS: macOS\n\n| Function           | Time (ns) | Speedup |\n|--------------------|----------:|--------:|\n| ostringstream      | 870.478   | 1.00x   |\n| sprintf            | 734.033   | 1.19x   |\n| double-conversion  | 82.903    | 10.50x  |\n| to_chars           | 42.537    | 20.46x  |\n| ryu                | 36.805    | 23.65x  |\n| schubfach          | 24.653    | 35.31x  |\n| fmt                | 22.201    | 39.21x  |\n| dragonbox          | 20.544    | 42.37x  |\n| yy                 | 13.963    | 62.34x  |\n| xjb64              | 10.500    | 82.90x  |\n| zmij               | 8.895     | 97.87x  |\n| null               | 0.929     | 936.55x |\n\n**Conversion time (smaller is better):**\n\n\u003cimg width=\"816\" height=\"358\" alt=\"image\" src=\"https://github.com/user-attachments/assets/c6eea19d-f824-4069-bc26-d701a419916e\" /\u003e\n\n`ostringstream` and `sprintf` are excluded due to their significantly slower\nperformance.\n\n\u003cimg width=\"857\" height=\"687\" alt=\"image\" src=\"https://github.com/user-attachments/assets/13cb86d3-4d76-4903-a13e-d4845a4388b4\" /\u003e\n\n### Notes\n\n* `null` performs no conversion and measures loop + call overhead.\n* `sprintf` and `ostringstream` do **not** generate shortest representations\n  (e.g. `0.1` → `0.10000000000000001`).\n* `ryu`, `dragonbox`, and `schubfach` always emit exponential notation\n  (e.g. `0.1` → `1E-1`).\n\nAdditional benchmark results are available in the\n[`results`](https://github.com/fmtlib/dtoa-benchmark/tree/main/results)\ndirectory and viewable online using\n[Google Charts](https://developers.google.com/chart/):\n\n* [apple-m1-pro_macos_clang17.0_e0a03f7](\n  https://fmtlib.github.io/dtoa-benchmark/results/apple-m1-pro_macos_clang17.0_f0f753f.html)\n\n## Methods\n\n| Function | Description |\n|----------|-------------|\n| [asteria](https://github.com/lhmouse/asteria) | `rocket::ascii_numput::put_DD` |\n| [double-conversion](https://github.com/google/double-conversion) | `EcmaScriptConverter::ToShortest` which implements Grisu3 with bignum fallback |\n| [dragonbox](https://github.com/jk-jeon/dragonbox) | `jkj::dragonbox::to_chars` with full tables |\n| [fmt](https://github.com/fmtlib/fmt) | `fmt::format_to` with compile-time format strings (uses Dragonbox). |\n| null | no-op implementation |\n| [ostringstream](https://en.cppreference.com/w/cpp/io/basic_ostringstream.html) | `std::ostringstream` with `setprecision(17)` |\n| [ryu](https://github.com/ulfjack/ryu) | `d2s_buffered` |\n| [schubfach](https://github.com/vitaut/schubfach) | C++ Schubfach implementation |\n| [sprintf](https://en.cppreference.com/w/c/io/fprintf.html) | C `sprintf(\"%.17g\", value)` |\n| [to_chars](https://en.cppreference.com/w/cpp/utility/to_chars.html) | `std::to_chars` |\n| [zmij](https://github.com/vitaut/zmij) | `zmij::write`. |\n\n### Notes\n\n`std::to_string` is excluded because it does **not** guarantee round-trip\ncorrectness (until C++26).\n\n## Why is fast `dtoa` important?\n\nFloating-point formatting is ubiquitous in text output. \nStandard facilities such as `sprintf` and `std::stringstream` are often slow.\nThis benchmark originated from performance work in\n[RapidJSON](https://github.com/miloyip/rapidjson/).\n\n## See Also\n\n* [Faster double-to-string conversion](https://vitaut.net/posts/2025/faster-dtoa/)\n* [The smallest state-of-the-art double-to-string implementation](\n  https://vitaut.net/posts/2025/smallest-dtoa/)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmtlib%2Fdtoa-benchmark","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffmtlib%2Fdtoa-benchmark","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffmtlib%2Fdtoa-benchmark/lists"}