NAME
    Acme::CPANModules::OrderedHash - List of modules that provide ordered
    hash data type

VERSION
    This document describes version 0.003 of Acme::CPANModules::OrderedHash
    (from Perl distribution Acme-CPANModules-OrderedHash), released on
    2023-10-06.

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 <https://metacpan.org/author/CHORNY>

    Hash::Ordered
        Author: DAGOLDEN <https://metacpan.org/author/DAGOLDEN>

    Tie::Hash::Indexed
        Author: MHX <https://metacpan.org/author/MHX>

        Provides two interfaces: tied hash and OO.

    Tie::LLHash
        Author: XAERXESS <https://metacpan.org/author/XAERXESS>

    Tie::StoredOrderHash
        Author: TFM <https://metacpan.org/author/TFM>

    Array::OrdHash
        Author: WOWASURIN <https://metacpan.org/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 <https://metacpan.org/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) [no_iterate]

        List::Unique::DeterministicOrder

BENCHMARK DATASETS
    *   insert 1000 pairs

    *   insert 1000 pairs + delete

    *   insert 1000 pairs + return keys 100 times

    *   insert 1000 pairs + iterate 10 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 4):

     #table1#
     {dataset=>"insert 1000 pairs"}
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+---------+---------+
     | participant                      | p_tags     | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors | samples |
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+---------+---------+
     | Tie::StoredOrderHash             |            |       360 |     2.78  |                 0.00% |               197.99% | 1.1e-06 |      20 |
     | Tie::LLHash                      |            |       380 |     2.6   |                 6.60% |               179.55% | 1.3e-05 |      20 |
     | Array::OrdHash                   |            |       540 |     1.9   |                49.87% |                98.83% | 3.2e-06 |      20 |
     | Tie::Hash::Indexed               |            |       700 |     2     |                81.84% |                63.87% | 7.2e-05 |      22 |
     | Tie::IxHash                      |            |       676 |     1.48  |                87.57% |                58.87% | 9.9e-07 |      20 |
     | Hash::Ordered                    |            |       884 |     1.13  |               145.25% |                21.50% | 1.1e-06 |      21 |
     | List::Unique::DeterministicOrder | no_iterate |      1070 |     0.931 |               197.99% |                 0.00% |   8e-07 |      21 |
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+---------+---------+

    The above result formatted in Benchmark.pm style:

                         Rate  T:S   T:L   TH:I   A:O   T:I   H:O   LU:D no_iterate 
      T:S               360/s    --   -6%   -28%  -31%  -46%  -59%             -66% 
      T:L               380/s    6%    --   -23%  -26%  -43%  -56%             -64% 
      TH:I              700/s   38%   30%     --   -5%  -26%  -43%             -53% 
      A:O               540/s   46%   36%     5%    --  -22%  -40%             -51% 
      T:I               676/s   87%   75%    35%   28%    --  -23%             -37% 
      H:O               884/s  146%  130%    76%   68%   30%    --             -17% 
      LU:D no_iterate  1070/s  198%  179%   114%  104%   58%   21%               -- 
 
     Legends:
       A:O : p_tags= participant=Array::OrdHash
       H:O : p_tags= participant=Hash::Ordered
       LU:D no_iterate: p_tags=no_iterate participant=List::Unique::DeterministicOrder
       T:I : p_tags= participant=Tie::IxHash
       T:L : p_tags= participant=Tie::LLHash
       T:S : p_tags= participant=Tie::StoredOrderHash
       TH:I : p_tags= participant=Tie::Hash::Indexed

    The above result presented as chart:

    Result formatted as table (split, part 2 of 4):

     #table2#
     {dataset=>"insert 1000 pairs + delete"}
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+---------+---------+
     | participant                      | p_tags     | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors | samples |
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+---------+---------+
     | Tie::IxHash                      |            |        17 |     58.8  |                 0.00% |              3799.19% | 4.1e-05 |      20 |
     | Tie::StoredOrderHash             |            |       200 |      5    |              1070.77% |               233.04% | 1.1e-05 |      20 |
     | Tie::LLHash                      |            |       220 |      4.6  |              1191.67% |               201.87% | 1.4e-05 |      21 |
     | Array::OrdHash                   |            |       279 |      3.59 |              1537.64% |               138.10% | 2.8e-06 |      21 |
     | Hash::Ordered                    |            |       370 |      2.7  |              2087.76% |                78.23% | 4.9e-06 |      20 |
     | List::Unique::DeterministicOrder | no_iterate |       604 |      1.66 |              3450.01% |                 9.84% | 5.1e-07 |      20 |
     | Tie::Hash::Indexed               |            |       663 |      1.51 |              3799.19% |                 0.00% |   6e-07 |      20 |
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+---------+---------+

    The above result formatted in Benchmark.pm style:

                        Rate   T:I   T:S   T:L   A:O   H:O   LU:D no_iterate  TH:I  
      T:I               17/s     --  -91%  -92%  -93%  -95%             -97%   -97% 
      T:S              200/s  1076%    --   -8%  -28%  -46%             -66%   -69% 
      T:L              220/s  1178%    8%    --  -21%  -41%             -63%   -67% 
      A:O              279/s  1537%   39%   28%    --  -24%             -53%   -57% 
      H:O              370/s  2077%   85%   70%   32%    --             -38%   -44% 
      LU:D no_iterate  604/s  3442%  201%  177%  116%   62%               --    -9% 
      TH:I             663/s  3794%  231%  204%  137%   78%               9%     -- 
 
     Legends:
       A:O : p_tags= participant=Array::OrdHash
       H:O : p_tags= participant=Hash::Ordered
       LU:D no_iterate: p_tags=no_iterate participant=List::Unique::DeterministicOrder
       T:I : p_tags= participant=Tie::IxHash
       T:L : p_tags= participant=Tie::LLHash
       T:S : p_tags= participant=Tie::StoredOrderHash
       TH:I : p_tags= participant=Tie::Hash::Indexed

    The above result presented as chart:

    Result formatted as table (split, part 3 of 4):

     #table3#
     {dataset=>"insert 1000 pairs + iterate 10 times"}
     +----------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+
     | participant          | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors | samples |
     +----------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+
     | Tie::LLHash          |      45   |      22   |                 0.00% |               206.84% | 4.1e-05 |      21 |
     | Tie::StoredOrderHash |      46   |      21.7 |                 2.02% |               200.75% | 9.4e-06 |      20 |
     | Array::OrdHash       |      51.4 |      19.5 |                13.93% |               169.32% | 1.4e-05 |      21 |
     | Tie::IxHash          |      65.1 |      15.4 |                44.41% |               112.47% | 9.4e-06 |      20 |
     | Tie::Hash::Indexed   |      97.5 |      10.3 |               116.20% |                41.93% | 9.3e-06 |      20 |
     | Hash::Ordered        |     140   |       7.2 |               206.84% |                 0.00% | 6.4e-05 |      20 |
     +----------------------+-----------+-----------+-----------------------+-----------------------+---------+---------+

    The above result formatted in Benchmark.pm style:

              Rate   T:L   T:S   A:O   T:I  TH:I   H:O 
      T:L     45/s    --   -1%  -11%  -29%  -53%  -67% 
      T:S     46/s    1%    --  -10%  -29%  -52%  -66% 
      A:O   51.4/s   12%   11%    --  -21%  -47%  -63% 
      T:I   65.1/s   42%   40%   26%    --  -33%  -53% 
      TH:I  97.5/s  113%  110%   89%   49%    --  -30% 
      H:O    140/s  205%  201%  170%  113%   43%    -- 
 
     Legends:
       A:O: participant=Array::OrdHash
       H:O: participant=Hash::Ordered
       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 4 of 4):

     #table4#
     {dataset=>"insert 1000 pairs + return keys 100 times"}
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
     | participant                      | p_tags     | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors   | samples |
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
     | Tie::StoredOrderHash             |            |      10.7 |     93.2  |                 0.00% |               845.55% | 5.8e-05   |      20 |
     | Tie::LLHash                      |            |      12   |     86    |                 8.76% |               769.40% |   0.00011 |      20 |
     | Array::OrdHash                   |            |      14   |     70    |                32.35% |               614.46% |   0.0001  |      20 |
     | Tie::IxHash                      |            |      16.2 |     61.8  |                50.70% |               527.45% | 5.4e-05   |      20 |
     | Tie::Hash::Indexed               |            |      24   |     41    |               124.79% |               320.64% |   0.0001  |      20 |
     | Hash::Ordered                    |            |      78.3 |     12.8  |               629.18% |                29.67% | 4.2e-06   |      20 |
     | List::Unique::DeterministicOrder | no_iterate |     101   |      9.85 |               845.55% |                 0.00% | 2.2e-06   |      22 |
     +----------------------------------+------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+

    The above result formatted in Benchmark.pm style:

                         Rate  T:S   T:L   A:O   T:I   TH:I   H:O   LU:D no_iterate 
      T:S              10.7/s    --   -7%  -24%  -33%   -56%  -86%             -89% 
      T:L                12/s    8%    --  -18%  -28%   -52%  -85%             -88% 
      A:O                14/s   33%   22%    --  -11%   -41%  -81%             -85% 
      T:I              16.2/s   50%   39%   13%    --   -33%  -79%             -84% 
      TH:I               24/s  127%  109%   70%   50%     --  -68%             -75% 
      H:O              78.3/s  628%  571%  446%  382%   220%    --             -23% 
      LU:D no_iterate   101/s  846%  773%  610%  527%   316%   29%               -- 
 
     Legends:
       A:O : p_tags= participant=Array::OrdHash
       H:O : p_tags= participant=Hash::Ordered
       LU:D no_iterate: p_tags=no_iterate participant=List::Unique::DeterministicOrder
       T:I : p_tags= participant=Tie::IxHash
       T:L : p_tags= participant=Tie::LLHash
       T:S : p_tags= participant=Tie::StoredOrderHash
       TH:I : p_tags= 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:

     #table5#
     +----------------------------------+-----------+-------------------+-----------------------+-----------------------+---------+---------+
     | participant                      | time (ms) | mod_overhead_time | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors | samples |
     +----------------------------------+-----------+-------------------+-----------------------+-----------------------+---------+---------+
     | List::Unique::DeterministicOrder |      16.2 |               8.5 |                 0.00% |               110.26% | 7.7e-06 |      20 |
     | Hash::Ordered                    |      15.9 |               8.2 |                 1.50% |               107.15% |   6e-06 |      20 |
     | Tie::Hash::Indexed               |      15.5 |               7.8 |                 4.57% |               101.06% | 4.9e-06 |      22 |
     | Array::OrdHash                   |      15   |               7.3 |                 7.86% |                94.94% | 1.1e-05 |      20 |
     | Tie::IxHash                      |      14.9 |               7.2 |                 8.49% |                93.81% |   9e-06 |      20 |
     | Tie::LLHash                      |      13.6 |               5.9 |                18.93% |                76.79% | 7.4e-06 |      20 |
     | Tie::StoredOrderHash             |      10.7 |               3   |                51.34% |                38.93% | 5.9e-06 |      20 |
     | perl -e1 (baseline)              |       7.7 |               0   |               110.26% |                 0.00% | 3.4e-05 |      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                  61.7/s    --   -1%   -4%  -7%  -8%  -16%  -33%                 -52% 
      H:O                   62.9/s    1%    --   -2%  -5%  -6%  -14%  -32%                 -51% 
      TH:I                  64.5/s    4%    2%    --  -3%  -3%  -12%  -30%                 -50% 
      A:O                   66.7/s    7%    6%    3%   --   0%   -9%  -28%                 -48% 
      T:I                   67.1/s    8%    6%    4%   0%   --   -8%  -28%                 -48% 
      T:L                   73.5/s   19%   16%   13%  10%   9%    --  -21%                 -43% 
      T:S                   93.5/s   51%   48%   44%  40%  39%   27%    --                 -28% 
      perl -e1 (baseline)  129.9/s  110%  106%  101%  94%  93%   76%   38%                   -- 
 
     Legends:
       A:O: mod_overhead_time=7.3 participant=Array::OrdHash
       H:O: mod_overhead_time=8.2 participant=Hash::Ordered
       LU:D: mod_overhead_time=8.5 participant=List::Unique::DeterministicOrder
       T:I: mod_overhead_time=7.2 participant=Tie::IxHash
       T:L: mod_overhead_time=5.9 participant=Tie::LLHash
       T:S: mod_overhead_time=3 participant=Tie::StoredOrderHash
       TH:I: mod_overhead_time=7.8 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".

BENCHMARK NOTES
    Hash::Ordered has strong performance in iterating and returning keys,
    while List::Unique::DeterministicOrder is strong in insertion and
    deletion (or Tie::Hash::Indexed if you're looking for actual hash type).

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-Orde
    redHash>

    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.

