NAME Acme::CPANModules::OrderedHash - List of modules that provide ordered hash data type VERSION This document describes version 0.002 of Acme::CPANModules::OrderedHash (from Perl distribution Acme-CPANModules-OrderedHash), released on 2023-10-05. SYNOPSIS To run benchmark with default option: % bencher --cpanmodules-module OrderedHash To run module startup overhead benchmark: % bencher --module-startup --cpanmodules-module OrderedHash For more options (dump scenario, list/include/exclude/add participants, list/include/exclude/add datasets, etc), see bencher or run "bencher --help". DESCRIPTION When you ask a Perl's hash for the list of keys, the answer comes back unordered. In fact, Perl explicitly randomizes the order of keys it returns everytime. The random ordering is a (security) feature, not a bug. However, sometimes you want to know the order of insertion. These modules provide you with an ordered hash; most of them implement it by recording the order of insertion of keys in an additional array. Other related modules: Tie::SortHash - will automatically sort keys when you call keys(), values(), each(). But this module does not maintain insertion order. ACME::CPANMODULES ENTRIES Tie::IxHash Author: CHORNY Hash::Ordered Author: DAGOLDEN Tie::Hash::Indexed Author: MHX Provides two interfaces: tied hash and OO. Tie::LLHash Author: XAERXESS Tie::StoredOrderHash Author: TFM Array::OrdHash Author: WOWASURIN Provide something closest to PHP's associative array, where you can refer elements by key or by numeric index, and insertion order is remembered. List::Unique::DeterministicOrder Author: SLAFFAN Provide a list, not hash. BENCHMARKED MODULES Version numbers shown below are the versions used when running the sample benchmark. Tie::IxHash 1.23 Hash::Ordered 0.014 Tie::Hash::Indexed 0.08 Tie::LLHash 1.004 Tie::StoredOrderHash 0.22 Array::OrdHash 1.03 List::Unique::DeterministicOrder 0.004 BENCHMARK PARTICIPANTS * Tie::IxHash (perl_code) Tie::IxHash * Hash::Ordered (perl_code) Hash::Ordered * Tie::Hash::Indexed (perl_code) Tie::Hash::Indexed * Tie::LLHash (perl_code) Tie::LLHash * Tie::StoredOrderHash (perl_code) Tie::StoredOrderHash * Array::OrdHash (perl_code) Array::OrdHash * List::Unique::DeterministicOrder (perl_code) List::Unique::DeterministicOrder BENCHMARK DATASETS * insert 1000 pairs * insert 1000 pairs + delete * insert 1000 pairs + return keys 100 times BENCHMARK SAMPLE RESULTS Sample benchmark #1 Run on: perl: *v5.38.0*, CPU: *Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz (2 cores)*, OS: *GNU/Linux Ubuntu version 20.04*, OS kernel: *Linux version 5.4.0-91-generic*. Benchmark command (default options): % bencher --cpanmodules-module OrderedHash Result formatted as table (split, part 1 of 3): #table1# {dataset=>"insert 1000 pairs"} +----------------------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+ | participant | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest | errors | samples | +----------------------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+ | Tie::StoredOrderHash | 360 | 2.78 | 0.00% | 199.08% | 2.6e-06 | 20 | | Tie::LLHash | 370 | 2.7 | 4.20% | 187.04% | 1.5e-05 | 20 | | Array::OrdHash | 540 | 1.8 | 51.22% | 97.78% | 2.5e-06 | 20 | | Tie::IxHash | 670 | 1.5 | 87.47% | 59.53% | 1.7e-06 | 20 | | Hash::Ordered | 889 | 1.13 | 147.19% | 20.99% | 8.6e-07 | 20 | | Tie::Hash::Indexed | 960 | 1 | 168.05% | 11.58% | 2.2e-06 | 21 | | List::Unique::DeterministicOrder | 1100 | 0.93 | 199.08% | 0.00% | 1.1e-06 | 20 | +----------------------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+ The above result formatted in Benchmark.pm style: Rate T:S T:L A:O T:I H:O TH:I LU:D T:S 360/s -- -2% -35% -46% -59% -64% -66% T:L 370/s 2% -- -33% -44% -58% -62% -65% A:O 540/s 54% 50% -- -16% -37% -44% -48% T:I 670/s 85% 80% 19% -- -24% -33% -38% H:O 889/s 146% 138% 59% 32% -- -11% -17% TH:I 960/s 177% 170% 80% 50% 12% -- -6% LU:D 1100/s 198% 190% 93% 61% 21% 7% -- Legends: A:O: participant=Array::OrdHash H:O: participant=Hash::Ordered LU:D: participant=List::Unique::DeterministicOrder T:I: participant=Tie::IxHash T:L: participant=Tie::LLHash T:S: participant=Tie::StoredOrderHash TH:I: participant=Tie::Hash::Indexed The above result presented as chart: Result formatted as table (split, part 2 of 3): #table2# {dataset=>"insert 1000 pairs + delete"} +----------------------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+ | participant | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest | errors | samples | +----------------------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+ | Tie::IxHash | 16.5 | 60.5 | 0.00% | 3719.19% | 4e-05 | 20 | | Tie::StoredOrderHash | 200 | 5.1 | 1081.74% | 223.18% | 1e-05 | 20 | | Tie::LLHash | 220 | 4.6 | 1219.38% | 189.47% | 9.5e-06 | 20 | | Array::OrdHash | 280 | 3.6 | 1577.30% | 127.70% | 6.4e-06 | 21 | | Hash::Ordered | 370 | 2.7 | 2110.87% | 72.75% | 8.4e-06 | 20 | | List::Unique::DeterministicOrder | 610 | 1.6 | 3607.28% | 3.02% | 2.2e-06 | 20 | | Tie::Hash::Indexed | 630 | 1.6 | 3719.19% | 0.00% | 9.3e-06 | 20 | +----------------------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+ The above result formatted in Benchmark.pm style: Rate T:I T:S T:L A:O H:O LU:D TH:I T:I 16.5/s -- -91% -92% -94% -95% -97% -97% T:S 200/s 1086% -- -9% -29% -47% -68% -68% T:L 220/s 1215% 10% -- -21% -41% -65% -65% A:O 280/s 1580% 41% 27% -- -25% -55% -55% H:O 370/s 2140% 88% 70% 33% -- -40% -40% LU:D 610/s 3681% 218% 187% 125% 68% -- 0% TH:I 630/s 3681% 218% 187% 125% 68% 0% -- Legends: A:O: participant=Array::OrdHash H:O: participant=Hash::Ordered LU:D: participant=List::Unique::DeterministicOrder T:I: participant=Tie::IxHash T:L: participant=Tie::LLHash T:S: participant=Tie::StoredOrderHash TH:I: participant=Tie::Hash::Indexed The above result presented as chart: Result formatted as table (split, part 3 of 3): #table3# {dataset=>"insert 1000 pairs + return keys 100 times"} +----------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+ | participant | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest | errors | samples | +----------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+ | Tie::StoredOrderHash | 10 | 96 | 0.00% | 885.35% | 0.00017 | 21 | | Tie::LLHash | 12 | 86 | 11.19% | 786.17% | 9.1e-05 | 20 | | Array::OrdHash | 13 | 75 | 28.17% | 668.78% | 0.00055 | 20 | | Tie::IxHash | 16 | 63 | 51.87% | 548.80% | 7.8e-05 | 20 | | Tie::Hash::Indexed | 24 | 41 | 131.40% | 325.82% | 0.00013 | 20 | | Hash::Ordered | 69 | 15 | 559.03% | 49.52% | 6.1e-05 | 20 | | List::Unique::DeterministicOrder | 100 | 9.7 | 885.35% | 0.00% | 1.1e-05 | 20 | +----------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+ The above result formatted in Benchmark.pm style: Rate T:S T:L A:O T:I TH:I H:O LU:D T:S 10/s -- -10% -21% -34% -57% -84% -89% T:L 12/s 11% -- -12% -26% -52% -82% -88% A:O 13/s 28% 14% -- -16% -45% -80% -87% T:I 16/s 52% 36% 19% -- -34% -76% -84% TH:I 24/s 134% 109% 82% 53% -- -63% -76% H:O 69/s 540% 473% 400% 320% 173% -- -35% LU:D 100/s 889% 786% 673% 549% 322% 54% -- Legends: A:O: participant=Array::OrdHash H:O: participant=Hash::Ordered LU:D: participant=List::Unique::DeterministicOrder T:I: participant=Tie::IxHash T:L: participant=Tie::LLHash T:S: participant=Tie::StoredOrderHash TH:I: participant=Tie::Hash::Indexed The above result presented as chart: Sample benchmark #2 Benchmark command (benchmarking module startup overhead): % bencher --cpanmodules-module OrderedHash --module-startup Result formatted as table: #table4# +----------------------------------+-----------+-------------------+-----------------------+-----------------------+-----------+---------+ | participant | time (ms) | mod_overhead_time | pct_faster_vs_slowest | pct_slower_vs_fastest | errors | samples | +----------------------------------+-----------+-------------------+-----------------------+-----------------------+-----------+---------+ | List::Unique::DeterministicOrder | 18 | 10 | 0.00% | 108.56% | 4.5e-05 | 20 | | Hash::Ordered | 16 | 8 | 10.05% | 89.52% | 4.4e-05 | 20 | | Tie::Hash::Indexed | 15 | 7 | 14.63% | 81.94% | 2.6e-05 | 21 | | Array::OrdHash | 15 | 7 | 18.44% | 76.10% | 1.7e-05 | 21 | | Tie::IxHash | 14.8 | 6.8 | 19.12% | 75.09% | 1.5e-05 | 20 | | Tie::LLHash | 14 | 6 | 29.30% | 61.30% | 2.5e-05 | 20 | | Tie::StoredOrderHash | 11 | 3 | 67.04% | 24.86% | 2.9e-05 | 20 | | perl -e1 (baseline) | 8 | 0 | 108.56% | 0.00% | 0.00015 | 20 | +----------------------------------+-----------+-------------------+-----------------------+-----------------------+-----------+---------+ The above result formatted in Benchmark.pm style: Rate LU:D H:O TH:I A:O T:I T:L T:S perl -e1 (baseline) LU:D 55.6/s -- -11% -16% -16% -17% -22% -38% -55% H:O 62.5/s 12% -- -6% -6% -7% -12% -31% -50% TH:I 66.7/s 19% 6% -- 0% -1% -6% -26% -46% A:O 66.7/s 19% 6% 0% -- -1% -6% -26% -46% T:I 67.6/s 21% 8% 1% 1% -- -5% -25% -45% T:L 71.4/s 28% 14% 7% 7% 5% -- -21% -42% T:S 90.9/s 63% 45% 36% 36% 34% 27% -- -27% perl -e1 (baseline) 125.0/s 125% 100% 87% 87% 85% 75% 37% -- Legends: A:O: mod_overhead_time=7 participant=Array::OrdHash H:O: mod_overhead_time=8 participant=Hash::Ordered LU:D: mod_overhead_time=10 participant=List::Unique::DeterministicOrder T:I: mod_overhead_time=6.8 participant=Tie::IxHash T:L: mod_overhead_time=6 participant=Tie::LLHash T:S: mod_overhead_time=3 participant=Tie::StoredOrderHash TH:I: mod_overhead_time=7 participant=Tie::Hash::Indexed perl -e1 (baseline): mod_overhead_time=0 participant=perl -e1 (baseline) The above result presented as chart: To display as an interactive HTML table on a browser, you can add option "--format html+datatables". FAQ What is an Acme::CPANModules::* module? An Acme::CPANModules::* module, like this module, contains just a list of module names that share a common characteristics. It is a way to categorize modules and document CPAN. See Acme::CPANModules for more details. What are ways to use this Acme::CPANModules module? Aside from reading this Acme::CPANModules module's POD documentation, you can install all the listed modules (entries) using cpanm-cpanmodules script (from App::cpanm::cpanmodules distribution): % cpanm-cpanmodules -n OrderedHash Alternatively you can use the cpanmodules CLI (from App::cpanmodules distribution): % cpanmodules ls-entries OrderedHash | cpanm -n or Acme::CM::Get: % perl -MAcme::CM::Get=OrderedHash -E'say $_->{module} for @{ $LIST->{entries} }' | cpanm -n or directly: % perl -MAcme::CPANModules::OrderedHash -E'say $_->{module} for @{ $Acme::CPANModules::OrderedHash::LIST->{entries} }' | cpanm -n This Acme::CPANModules module contains benchmark instructions. You can run a benchmark for some/all the modules listed in this Acme::CPANModules module using the bencher CLI (from Bencher distribution): % bencher --cpanmodules-module OrderedHash This Acme::CPANModules module also helps lcpan produce a more meaningful result for "lcpan related-mods" command when it comes to finding related modules for the modules listed in this Acme::CPANModules module. See App::lcpan::Cmd::related_mods for more details on how "related modules" are found. HOMEPAGE Please visit the project's homepage at . SOURCE Source repository is at . SEE ALSO Acme::CPANModules::HashUtilities Acme::CPANModules - about the Acme::CPANModules namespace cpanmodules - CLI tool to let you browse/view the lists AUTHOR perlancar CONTRIBUTING To contribute, you can send patches by email/via RT, or send pull requests on GitHub. Most of the time, you don't need to build the distribution yourself. You can simply modify the code, then test via: % prove -l If you want to build the distribution (e.g. to try to install it locally on your system), you can install Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, Pod::Weaver::PluginBundle::Author::PERLANCAR, and sometimes one or two other Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond that are considered a bug and can be reported to me. COPYRIGHT AND LICENSE This software is copyright (c) 2023 by perlancar . This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. BUGS Please report any bugs or feature requests on the bugtracker website When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.