{"id":18266264,"url":"https://github.com/hdrhistogram/hdr_histogram_erl","last_synced_at":"2025-09-04T17:52:10.674Z","repository":{"id":23295144,"uuid":"26654351","full_name":"HdrHistogram/hdr_histogram_erl","owner":"HdrHistogram","description":"High Dynamic Range HDR Histogram for Erlang/OTP, Elixir \u0026 LFE","archived":false,"fork":false,"pushed_at":"2023-08-21T21:09:44.000Z","size":133,"stargazers_count":101,"open_issues_count":2,"forks_count":37,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-03-29T23:09:07.900Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","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/HdrHistogram.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-11-14T19:38:30.000Z","updated_at":"2025-01-30T16:50:43.000Z","dependencies_parsed_at":"2024-06-21T15:34:38.503Z","dependency_job_id":"073199ac-04c2-4d62-a341-9cbe01bccf8c","html_url":"https://github.com/HdrHistogram/hdr_histogram_erl","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2Fhdr_histogram_erl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2Fhdr_histogram_erl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2Fhdr_histogram_erl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HdrHistogram%2Fhdr_histogram_erl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HdrHistogram","download_url":"https://codeload.github.com/HdrHistogram/hdr_histogram_erl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247415967,"owners_count":20935387,"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":[],"created_at":"2024-11-05T11:22:39.704Z","updated_at":"2025-04-06T00:09:37.026Z","avatar_url":"https://github.com/HdrHistogram.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hdr_histogram_erl\n\n![Common Test](https://github.com/hdrhistogram/hdr_histogram_erl/workflows/Common%20Test/badge.svg) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/HdrHistogram/HdrHistogram?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge) [\u003cimg src=\"http://quickcheck-ci.com/p/hdrhistogram/hdr_histogram_erl.png\" alt=\"Build Status\" width=\"100px\" height=\"18px\"\u003e](http://quickcheck-ci.com/p/hdrhistogram/hdr_histogram_erl)\n\n## Description ##\n\nThe HDR histogram library is an Erlang native interface function wrapper of\nMike Barker's C port of Gil Tene's HDR Histogram utility.\n\nA high dynamic range histogram is one that supports recording and analyzing\nsampled data points across a configurable range with configurable precision\nwithin that range. The precision is expressed as a number of significant\nfigures in the recording.\n\n\nThis HDR histogram implementation is designed for recording histograms of\nvalue measurements in latency sensitive environments. Although the native\nrecording times can be as low as single digit nanoseconds there is added\noverhead in this wrapper/binding due to both the frontend overhead of converting\nfrom native C to the NIF interface, and the erlang overhead incurred calling\ninto the NIFs. C'est la vie, I suppose.\n\n\nA distinct advantage of this histogram implementation is constant space and\nrecording (time) overhead with an ability to recycle and reset instances whilst\nreclaiming already allocated space for reuse thereby reducing allocation cost\nand garbage collection overhead in the BEAM where repeated or continuous usage\nis likely. For example, a gen_server recording metrics continuously and resetting\nand logging histogram dumps on a periodic or other windowed basis.\n\n\n\nThe code is released to the public domain, under the same terms as its\nsibling projects, as explained in the LICENSE.txt and COPYING.txt in the\nroot of this repository, but normatively at:\n\nhttp://creativecommons.org/publicdomain/zero/1.0/\n\n### Examples\n\nCapture metrics and produce a histogram using Erlang/OTP:\n\n\n```erlang\n#!/usr/bin/env escript\n%%! -sname hdr_histogram_simple -pa ebin\n\n-mode(compile).\n\n%\n% Simple histogram capture example using Erlang\n%\n\nloop(_,0) -\u003e ok;\nloop(R,X) -\u003e hdr_histogram:record(R,random:uniform(1000000)), loop(R,X-1).\n\nmain(_) -\u003e\n    {ok,R} = hdr_histogram:open(1000000,3),\n    N = 10000000, %2.2 million/sec on my laptop but YMMV\n\n    %% record a random uniform distribution of 1M data points\n    S = os:timestamp(),\n    loop(R, N),\n    E = os:timestamp(),\n    X = timer:now_diff(E,S)/1.0e6,\n    Y = case X\u003e1 of true -\u003e N/X; false -\u003e N*X end,\n    io:format(\"Runtime: ~psecs ~.5frps~n\", [X,Y]),\n\n    %% print percentiles to stdout as CSV\n    hdr_histogram:print(R,csv),\n\n    %% print percentiles to stdout as CLASSIC\n    hdr_histogram:log(R,classic,\"erlang.hgrm\"),\n\n    io:format(\"Min ~p~n\", [hdr_histogram:min(R)]),\n    io:format(\"Mean ~.3f~n\", [hdr_histogram:mean(R)]),\n    io:format(\"Median ~.3f~n\", [hdr_histogram:median(R)]),\n    io:format(\"Max ~p~n\", [hdr_histogram:max(R)]),\n    io:format(\"Stddev ~.3f~n\", [hdr_histogram:stddev(R)]),\n    io:format(\"99ile ~.3f~n\", [hdr_histogram:percentile(R,99.0)]),\n    io:format(\"99.9999ile ~.3f~n\", [hdr_histogram:percentile(R,99.9999)]),\n    io:format(\"Memory Size ~p~n\", [hdr_histogram:get_memory_size(R)]),\n    io:format(\"Total Count ~p~n\", [hdr_histogram:get_total_count(R)]),\n\n    %% we're done, cleanup any held resources\n    hdr_histogram:close(R),\n\n    io:format(\"Done!\\n\").\n```\n\nThe same library works with other BEAM hosted languages, such as Elixir. See `examples/simple.exs`.\n\n[API documentation](doc/README.md)\n\n## A note on tuning ##\n\n\nA common useage example of HdrHistogram is to record response times, in units ofmicroseconds, across a dynamic range stretching from 1 usec to over an hour. We want a good enough resolution to support performing post-recording analysis on the collected data at some future time.\n\nIn order to facilitate the accuracy needed for such post-recording activities, we can maintain a resolution of ~1 usec or better for times ranging to ~2 msec in magnitude, while at the same time maintaining a resolution of ~1 msec or better for times ranging to ~2 sec, and a resolution of ~1 second or better for values up to 2,000 seconds, and so on. This sort of dynamic resolution can be thought of as \"always accurate to 3 decimal points\".\n\nA HDR Histogram works like this. We MUST tune the highest trackable value to 3,600,000,000, and the number of significant value digits of 3. This range is fixed, and occupies a fixed, unchanging memory footprint of around 185KB.\n\n## A note on footprint estimation ##\n\n\nDue to it's **dynamic range** representation, HDR Histogram is relatively efficient in memory space requirements given the accuracy and dynamic range that it covers.\n\nStill, it is useful to be able to estimate the memory footprint involved for a given highest trackable value and the configured number of significant value digits combination. Beyond a relatively small fixed-size footprint used for internal fields and stats (which can be estimated as \"fixed at well less than 1KB\"), the bulk of a histogram's storage is taken up by it's data value recording counts array. The total footprint can be conservatively estimated by:\n\n```\n largestValueWithSingleUnitResolution =\n        2 * (10 ^ numberOfSignificantValueDigits);\n subBucketSize =\n        roundedUpToNearestPowerOf2(largestValueWithSingleUnitResolution);\n\n expectedHistogramFootprintInBytes = 512 +\n      ({primitive type size} / 2) *\n      (log2RoundedUp((highestTrackableValue) / subBucketSize) + 2) *\n      subBucketSize\n```\n\nA conservative (high) estimate of a Histogram's footprint in bytes is available via thegetEstimatedFootprintInBytes() method.\n\n## A note on concurrent access ##\n\nHdrHistogram does *NOT* have any internal synchronization and at present hdr_histogram_erl does *NOT* provide any synchronization. This means that a Histogram reference must not be written to or read from multiple processes. \n\nIt is recommended that you either wrap an hdr_histogram in a process, thus serializing access. It is also possible to use `hdr_histogram:add/2` to aggregate the contents of two histograms, making it possible to utilize per-process histograms that are aggregated by a separate reporting process.\n\n## Enjoy!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhdrhistogram%2Fhdr_histogram_erl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhdrhistogram%2Fhdr_histogram_erl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhdrhistogram%2Fhdr_histogram_erl/lists"}