NAME
Acme::CPANModules::OrderedHash - List of modules that provide ordered hash data type
VERSION
This document describes version 0.001 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)
Hash::Ordered (perl_code)
Tie::Hash::Indexed (perl_code)
Tie::LLHash (perl_code)
Tie::StoredOrderHash (perl_code)
Array::OrdHash (perl_code)
List::Unique::DeterministicOrder (perl_code)
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::LLHash | 200 | 4 | 0.00% | 333.85% | 0.00013 | 20 |
| Tie::StoredOrderHash | 350 | 2.9 | 41.84% | 205.88% | 7.5e-06 | 20 |
| Array::OrdHash | 540 | 1.8 | 118.76% | 98.32% | 2.1e-06 | 20 |
| Hash::Ordered | 600 | 2 | 129.15% | 89.33% | 8.7e-05 | 32 |
| Tie::IxHash | 670 | 1.5 | 169.83% | 60.78% | 2.5e-06 | 20 |
| Tie::Hash::Indexed | 700 | 1 | 187.24% | 51.04% | 5.7e-05 | 20 |
| List::Unique::DeterministicOrder | 1100 | 0.93 | 333.85% | 0.00% | 2.3e-06 | 20 |
+----------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
The above result formatted in Benchmark.pm style:
Rate T:L T:S H:O A:O T:I TH:I LU:D
T:L 200/s -- -27% -50% -55% -62% -75% -76%
T:S 350/s 37% -- -31% -37% -48% -65% -67%
H:O 600/s 100% 44% -- -9% -25% -50% -53%
A:O 540/s 122% 61% 11% -- -16% -44% -48%
T:I 670/s 166% 93% 33% 19% -- -33% -38%
TH:I 700/s 300% 190% 100% 80% 50% -- -6%
LU:D 1100/s 330% 211% 115% 93% 61% 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:
#IMAGE: share/images/bencher-result-1.png|/tmp/dxS0EuAWVP/bencher-result-1.png
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 | 15 | 67 | 0.00% | 4003.59% | 0.00034 | 20 |
| Tie::StoredOrderHash | 200 | 6 | 1082.65% | 246.98% | 8.4e-05 | 21 |
| Tie::LLHash | 200 | 5 | 1119.91% | 236.39% | 0.00013 | 20 |
| Array::OrdHash | 270 | 3.8 | 1686.96% | 129.64% | 1.5e-05 | 20 |
| Hash::Ordered | 300 | 3 | 2008.58% | 94.61% | 3.4e-05 | 22 |
| Tie::Hash::Indexed | 500 | 2 | 3188.02% | 24.80% | 6.7e-05 | 20 |
| List::Unique::DeterministicOrder | 610 | 1.6 | 4003.59% | 0.00% | 4.3e-06 | 20 |
+----------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
The above result formatted in Benchmark.pm style:
Rate T:I T:S T:L A:O H:O TH:I LU:D
T:I 15/s -- -91% -92% -94% -95% -97% -97%
T:S 200/s 1016% -- -16% -36% -50% -66% -73%
T:L 200/s 1240% 19% -- -24% -40% -60% -68%
A:O 270/s 1663% 57% 31% -- -21% -47% -57%
H:O 300/s 2133% 100% 66% 26% -- -33% -46%
TH:I 500/s 3250% 200% 150% 89% 50% -- -19%
LU:D 610/s 4087% 275% 212% 137% 87% 25% --
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:
#IMAGE: share/images/bencher-result-2.png|/tmp/dxS0EuAWVP/bencher-result-2.png
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::LLHash | 8 | 100 | 0.00% | 1061.27% | 0.0049 | 20 |
| Tie::StoredOrderHash | 8 | 100 | 3.73% | 1019.53% | 0.0019 | 20 |
| Array::OrdHash | 13 | 79 | 56.42% | 642.39% | 0.00048 | 21 |
| Tie::IxHash | 15 | 69 | 80.98% | 541.64% | 0.00015 | 20 |
| Tie::Hash::Indexed | 20 | 50 | 148.79% | 366.76% | 0.00071 | 20 |
| Hash::Ordered | 61 | 16 | 662.88% | 52.22% | 0.00011 | 20 |
| List::Unique::DeterministicOrder | 94 | 11 | 1061.27% | 0.00% | 9.1e-05 | 20 |
+----------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
The above result formatted in Benchmark.pm style:
Rate T:L T:S A:O T:I TH:I H:O LU:D
T:L 8/s -- 0% -20% -31% -50% -84% -89%
T:S 8/s 0% -- -20% -31% -50% -84% -89%
A:O 13/s 26% 26% -- -12% -36% -79% -86%
T:I 15/s 44% 44% 14% -- -27% -76% -84%
TH:I 20/s 100% 100% 58% 37% -- -68% -78%
H:O 61/s 525% 525% 393% 331% 212% -- -31%
LU:D 94/s 809% 809% 618% 527% 354% 45% --
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:
#IMAGE: share/images/bencher-result-3.png|/tmp/dxS0EuAWVP/bencher-result-3.png
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 |
+----------------------------------+-----------+-------------------+-----------------------+-----------------------+---------+---------+
| Tie::LLHash | 20 | 10 | 0.00% | 142.41% | 0.00081 | 20 |
| Hash::Ordered | 20 | 10 | 19.61% | 102.67% | 0.00039 | 20 |
| Tie::Hash::Indexed | 20 | 10 | 21.42% | 99.65% | 0.00044 | 21 |
| List::Unique::DeterministicOrder | 19 | 9 | 25.72% | 92.82% | 0.00017 | 21 |
| Tie::IxHash | 20 | 10 | 36.08% | 78.13% | 0.00023 | 21 |
| Array::OrdHash | 16 | 6 | 46.94% | 64.97% | 0.0001 | 20 |
| Tie::StoredOrderHash | 20 | 10 | 52.27% | 59.20% | 0.00075 | 20 |
| perl -e1 (baseline) | 10 | 0 | 142.41% | 0.00% | 0.00027 | 20 |
+----------------------------------+-----------+-------------------+-----------------------+-----------------------+---------+---------+
The above result formatted in Benchmark.pm style:
Rate T:L H:O TH:I T:I T:S LU:D A:O perl -e1 (baseline)
T:L 50.0/s -- 0% 0% 0% 0% -5% -19% -50%
H:O 50.0/s 0% -- 0% 0% 0% -5% -19% -50%
TH:I 50.0/s 0% 0% -- 0% 0% -5% -19% -50%
T:I 50.0/s 0% 0% 0% -- 0% -5% -19% -50%
T:S 50.0/s 0% 0% 0% 0% -- -5% -19% -50%
LU:D 52.6/s 5% 5% 5% 5% 5% -- -15% -47%
A:O 62.5/s 25% 25% 25% 25% 25% 18% -- -37%
perl -e1 (baseline) 100.0/s 100% 100% 100% 100% 100% 89% 60% --
Legends:
A:O: mod_overhead_time=6 participant=Array::OrdHash
H:O: mod_overhead_time=10 participant=Hash::Ordered
LU:D: mod_overhead_time=9 participant=List::Unique::DeterministicOrder
T:I: mod_overhead_time=10 participant=Tie::IxHash
T:L: mod_overhead_time=10 participant=Tie::LLHash
T:S: mod_overhead_time=10 participant=Tie::StoredOrderHash
TH:I: mod_overhead_time=10 participant=Tie::Hash::Indexed
perl -e1 (baseline): mod_overhead_time=0 participant=perl -e1 (baseline)
The above result presented as chart:
#IMAGE: share/images/bencher-result-4.png|/tmp/dxS0EuAWVP/bencher-result-4.png
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 https://metacpan.org/release/Acme-CPANModules-OrderedHash.
SOURCE
Source repository is at https://github.com/perlancar/perl-Acme-CPANModules-OrderedHash.
SEE ALSO
Acme::CPANModules::HashUtilities
Acme::CPANModules - about the Acme::CPANModules namespace
cpanmodules - CLI tool to let you browse/view the lists
AUTHOR
perlancar <perlancar@cpan.org>
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 <perlancar@cpan.org>.
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 https://rt.cpan.org/Public/Dist/Display.html?Name=Acme-CPANModules-OrderedHash
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.