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 <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)

        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
    <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.