{"id":18266259,"url":"https://github.com/hdrhistogram/hdrhistogram_rust","last_synced_at":"2025-05-15T09:08:17.411Z","repository":{"id":41483196,"uuid":"62972117","full_name":"HdrHistogram/HdrHistogram_rust","owner":"HdrHistogram","description":"A port of HdrHistogram to Rust","archived":false,"fork":false,"pushed_at":"2024-03-21T12:05:17.000Z","size":1018,"stargazers_count":321,"open_issues_count":23,"forks_count":41,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-05-15T09:08:09.866Z","etag":null,"topics":["hdrhistogram","profiling","rust","sampling","statistical-analysis"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HdrHistogram.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE-APACHE","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}},"created_at":"2016-07-09T22:47:57.000Z","updated_at":"2025-04-21T19:33:07.000Z","dependencies_parsed_at":"2024-06-18T16:55:10.940Z","dependency_job_id":"d2d7a5a8-11f9-4c2d-b154-2d89a6a1d20b","html_url":"https://github.com/HdrHistogram/HdrHistogram_rust","commit_stats":{"total_commits":332,"total_committers":23,"mean_commits":"14.434782608695652","dds":0.5030120481927711,"last_synced_commit":"a3818d6ce81556010c7f04f423e1fa28a9ff1b5c"},"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2FHdrHistogram_rust","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2FHdrHistogram_rust/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2FHdrHistogram_rust/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2FHdrHistogram_rust/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HdrHistogram","download_url":"https://codeload.github.com/HdrHistogram/HdrHistogram_rust/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254310520,"owners_count":22049470,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["hdrhistogram","profiling","rust","sampling","statistical-analysis"],"created_at":"2024-11-05T11:22:39.017Z","updated_at":"2025-05-15T09:08:12.402Z","avatar_url":"https://github.com/HdrHistogram.png","language":"Rust","readme":"# HdrHistogram_rust\n\n[![Crates.io](https://img.shields.io/crates/v/hdrhistogram.svg)](https://crates.io/crates/hdrhistogram)\n[![Documentation](https://docs.rs/hdrhistogram/badge.svg)](https://docs.rs/hdrhistogram/)\n[![Codecov](https://codecov.io/github/HdrHistogram/HdrHistogram_rust/coverage.svg?branch=master)](https://codecov.io/gh/HdrHistogram/HdrHistogram_rust)\n[![Dependency status](https://deps.rs/repo/github/HdrHistogram/HdrHistogram_rust/status.svg)](https://deps.rs/repo/github/HdrHistogram/HdrHistogram_rust)\n\nHdrSample is a port of Gil Tene's HdrHistogram to native Rust. It provides recording and\nanalyzing of sampled data value counts across a large, configurable value range with\nconfigurable precision within the range. The resulting \"HDR\" histogram allows for fast and\naccurate analysis of the extreme ranges of data with non-normal distributions, like latency.\n\n## HdrHistogram\n\nWhat follows is a description from [the HdrHistogram\nwebsite](https://hdrhistogram.github.io/HdrHistogram/). Users are encouraged to read the\ndocumentation from the original [Java\nimplementation](https://github.com/HdrHistogram/HdrHistogram), as most of the concepts\ntranslate directly to the Rust port.\n\nHdrHistogram supports the recording and analyzing of sampled data value counts across a\nconfigurable integer value range with configurable value precision within the range. Value\nprecision is expressed as the number of significant digits in the value recording, and provides\ncontrol over value quantization behavior across the value range and the subsequent value\nresolution at any given level.\n\nFor example, a Histogram could be configured to track the counts of observed integer values\nbetween 0 and 3,600,000,000 while maintaining a value precision of 3 significant digits across\nthat range. Value quantization within the range will thus be no larger than 1/1,000th (or 0.1%)\nof any value. This example Histogram could be used to track and analyze the counts of observed\nresponse times ranging between 1 microsecond and 1 hour in magnitude, while maintaining a value\nresolution of 1 microsecond up to 1 millisecond, a resolution of 1 millisecond (or better) up\nto one second, and a resolution of 1 second (or better) up to 1,000 seconds. At it's maximum\ntracked value (1 hour), it would still maintain a resolution of 3.6 seconds (or better).\n\nHDR Histogram is designed for recording histograms of value measurements in latency and\nperformance sensitive applications. Measurements show value recording times as low as 3-6\nnanoseconds on modern (circa 2014) Intel CPUs. The HDR Histogram maintains a fixed cost in both\nspace and time. A Histogram's memory footprint is constant, with no allocation operations\ninvolved in recording data values or in iterating through them. The memory footprint is fixed\nregardless of the number of data value samples recorded, and depends solely on the dynamic\nrange and precision chosen. The amount of work involved in recording a sample is constant, and\ndirectly computes storage index locations such that no iteration or searching is ever involved\nin recording data values.\n\nIf you are looking for FFI bindings to\n[`HdrHistogram_c`](https://github.com/HdrHistogram/HdrHistogram_c), you want the\n[`hdrhistogram_c`](https://crates.io/crates/hdrhistogram_c) crate instead.\n\n## Interacting with the library\n\nHdrSample's API follows that of the original HdrHistogram Java implementation, with some\nmodifications to make its use more idiomatic in Rust. The description in this section has been\nadapted from that given by the [Python port](https://github.com/HdrHistogram/HdrHistogram_py),\nas it gives a nicer first-time introduction to the use of HdrHistogram than the Java docs do.\n\nHdrSample is generally used in one of two modes: recording samples, or querying for analytics.\nIn distributed deployments, the recording may be performed remotely (and possibly in multiple\nlocations), to then be aggregated later in a central location for analysis.\n\n### Recording samples\n\nA histogram instance is created using the `::new` methods on the `Histogram` struct. These come\nin three variants: `new`, `new_with_max`, and `new_with_bounds`. The first of these only sets\nthe required precision of the sampled data, but leaves the value range open such that any value\nmay be recorded. A `Histogram` created this way (or one where auto-resize has been explicitly\nenabled) will automatically resize itself if a value that is too large to fit in the current\ndataset is encountered. `new_with_max` sets an upper bound on the values to be recorded, and\ndisables auto-resizing, thus preventing any re-allocation during recording. If the application\nattempts to record a larger value than this maximum bound, the `record` call will return an\nerror. Finally, `new_with_bounds` restricts the lowest representable value of the dataset,\nsuch that a smaller range needs to be covered (thus reducing the overall allocation size).\n\nFor example the example below shows how to create a `Histogram` that can count values in the\n`[1..3600000]` range with 1% precision, which could be used to track latencies in the range `[1\nmsec..1 hour]`).\n\n```rust\nuse hdrhistogram::Histogram;\nlet mut hist = Histogram::\u003cu64\u003e::new_with_bounds(1, 60 * 60 * 1000, 2).unwrap();\n\n// samples can be recorded using .record, which will error if the value is too small or large\nhist.record(54321).expect(\"value 54321 should be in range\");\n\n// for ergonomics, samples can also be recorded with +=\n// this call will panic if the value is out of range!\nhist += 54321;\n\n// if the code that generates the values is subject to Coordinated Omission,\n// the self-correcting record method should be used instead.\n// for example, if the expected sampling interval is 10 msec:\nhist.record_correct(54321, 10).expect(\"value 54321 should be in range\");\n```\n\nNote the `u64` type. This type can be changed to reduce the storage overhead for all the\nhistogram bins, at the cost of a risk of saturating if a large number of samples end up in the\nsame bin.\n\n### Querying samples\n\nAt any time, the histogram can be queried to return interesting statistical measurements, such\nas the total number of recorded samples, or the value at a given quantile:\n\n```rust\nuse hdrhistogram::Histogram;\nlet hist = Histogram::\u003cu64\u003e::new(2).unwrap();\n// ...\nprintln!(\"# of samples: {}\", hist.len());\nprintln!(\"99.9'th percentile: {}\", hist.value_at_quantile(0.999));\n```\n\nSeveral useful iterators are also provided for quickly getting an overview of the dataset. The\nsimplest one is `iter_recorded()`, which yields one item for every non-empty sample bin. All\nthe HdrHistogram iterators are supported in HdrSample, so look for the `*Iterator` classes in\nthe [Java documentation](https://hdrhistogram.github.io/HdrHistogram/JavaDoc/).\n\n```rust\nuse hdrhistogram::Histogram;\nlet hist = Histogram::\u003cu64\u003e::new(2).unwrap();\n// ...\nfor v in hist.iter_recorded() {\n    println!(\"{}'th percentile of data is {} with {} samples\",\n        v.percentile(), v.value_iterated_to(), v.count_at_value());\n}\n```\n\n### Panics and error handling\n\nAs long as you're using safe, non-panicking functions (see below), this library should never\npanic. Any panics you encounter are a bug; please file them in the issue tracker.\n\nA few functions have their functionality exposed via `AddAssign` and `SubAssign`\nimplementations. These alternate forms are equivalent to simply calling `unwrap()` on the\nnormal functions, so the normal rules of `unwrap()` apply: view with suspicion when used in\nproduction code, etc.\n\n| Returns Result                 | Panics on error    | Functionality                   |\n| ------------------------------ | ------------------ | ------------------------------- |\n| `h.record(v)`                  | `h += v`           | Increment count for value `v`   |\n| `h.add(h2)`                    | `h += h2`          | Add `h2`'s counts to `h`        |\n| `h.subtract(h2)`               | `h -= h2`          | Subtract `h2`'s counts from `h` |\n\nOther than the panicking forms of the above functions, everything will return `Result` or\n`Option` if it can fail.\n\n### `usize` limitations\n\nDepending on the configured number of significant digits and maximum value, a histogram's\ninternal storage may have hundreds of thousands of cells. Systems with a 16-bit `usize` cannot\nrepresent pointer offsets that large, so relevant operations (creation, deserialization, etc)\nwill fail with a suitable error (e.g. `CreationError::UsizeTypeTooSmall`). If you are using such\na system and hitting these errors, reducing the number of significant digits will greatly reduce\nmemory consumption (and therefore the need for large `usize` values). Lowering the max value may\nalso help as long as resizing is disabled.\n\n32- and above systems will not have any such issues, as all possible histograms fit within a\n32-bit index.\n\n### Floating point accuracy\n\nSome calculations inherently involve floating point values, like `value_at_quantile`, and are\ntherefore subject to the precision limits of IEEE754 floating point calculations. The user-\nvisible consequence of this is that in certain corner cases, you might end up with a bucket (and\ntherefore value) that is higher or lower than it would be if the calculation had been done\nwith arbitrary-precision arithmetic. However, double-precision IEEE754 (i.e. `f64`) is very\ngood at its job, so these cases should be rare. Also, we haven't seen a case that was off by\nmore than one bucket.\n\nTo minimize FP precision losses, we favor working with quantiles rather than percentiles. A\nquantile represents a portion of a set with a number in `[0, 1]`. A percentile is the same\nconcept, except it uses the range `[0, 100]`. Working just with quantiles means we can skip an\nFP operation in a few places, and therefore avoid opportunities for precision loss to creep in.\n\n## Limitations and Caveats\n\nAs with all the other HdrHistogram ports, the latest features and bug fixes from the upstream\nHdrHistogram implementations may not be available in this port. A number of features have also\nnot (yet) been implemented:\n\n - Concurrency support (`AtomicHistogram`, `ConcurrentHistogram`, …).\n - `DoubleHistogram`.\n - The `Recorder` feature of HdrHistogram.\n - Value shifting (\"normalization\").\n - Textual output methods. These seem almost orthogonal to HdrSample, though it might be\n   convenient if we implemented some relevant traits (CSV, JSON, and possibly simple\n   `fmt::Display`).\n\nMost of these should be fairly straightforward to add, as the code aligns pretty well with the\noriginal Java/C# code. If you do decide to implement one and send a PR, please make sure you\nalso port the [test\ncases](https://github.com/HdrHistogram/HdrHistogram/tree/master/src/test/java/org/HdrHistogram),\nand try to make sure you implement appropriate traits to make the use of the feature as\nergonomic as possible.\n\n## Usage\n\nAdd this to your `Cargo.toml`:\n\n```toml\n[dependencies]\nhdrhistogram = \"7\"\n```\n\nand this to your crate root:\n\n```rust\nextern crate hdrhistogram;\n```\n\n## License\n\nDual-licensed to be compatible with the Rust project.\n\nLicensed under the Apache License, Version 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0 or the MIT license\nhttp://opensource.org/licenses/MIT, at your option. This file may not be\ncopied, modified, or distributed except according to those terms.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhdrhistogram%2Fhdrhistogram_rust","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhdrhistogram%2Fhdrhistogram_rust","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhdrhistogram%2Fhdrhistogram_rust/lists"}