package Acme::CPANModules::UUID;

use strict;
use warnings;

our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
our $DATE = '2023-10-30'; # DATE
our $DIST = 'Acme-CPANModules-UUID'; # DIST
our $VERSION = '0.011'; # VERSION

our $LIST = {
    summary => 'List of modules that can generate immutable universally unique identifier (UUIDs)',
    description => <<'MARKDOWN',

UUIDs (Universally Unique Identifiers), sometimes also called GUIDs (Globally
Unique Identifiers), are 128-bit numbers that can be used as permanent IDs or
keys in databases. There are several standards that specify UUID, one of which
is RFC 4122 (2005), which we will follow in this document.

UUIDs are canonically represented as 32 hexadecimal digits in the form of:

    xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

There are several variants of UUID. The variant information is encoded using 1-3
bits in the `N` position. RFC 4122 defines 4 variants (0 to 3), two of which (0
and 3) are for legacy UUIDs, so that leaves variants 1 and 2 as the current
specification.

There are 5 "versions" of UUID for both variants 1 & 2, each might be more
suitable than others in specific cases. The version information is encoded in
the M position. Version 1 (v1) UUIDs are generated from a time and a node ID
(usually the MAC address); version 2 (v2) UUIDs from an identifier (group/user
ID), a time, and a node ID; version 4 (v4) UUIDs from a rando/mpseudo-random
number; version 3 (v3) UUIDs from hashing a namespace using MD5; version 5 (v5)
from hashing a namespace using SHA-1.

<pm:Data::UUID> should be your first choice, and when you cannot install XS
modules you can use <pm:UUID::Tiny> instead.

Aside from the modules listed as entries below, there are also:
<pm:App::UUIDUtils> (containing CLIs to create/check UUID), <pm:Data::GUID>
(currently just a wrapper for Data::UUID).

MARKDOWN
    entry_features => {
        v4_rfc4122 => {summary => 'Whether the generated v4 UUID follows RFC 4122 specification (i.e. encodes variant and version information in M & N positions)'},
        v4_secure_random => {summary => 'Whether the module uses cryptographically secure pseudo-random number generator for v4 UUIDs'},
    },
    entries => [
        {
            module => 'Data::UUID',
            description => <<'MARKDOWN',

This module creates v1 and v2 UUIDs. Depending on the OS, for MAC address, it
usually uses a hash of hostname instead. This module is XS, so performance is
good. If you cannot use an XS module, try <pm:UUID::Tiny> instead.

The benchmark code creates 1000+1 v1 string UUIDs.

MARKDOWN
            bench_code_template => 'my $u = Data::UUID->new; $u->create for 1..1000; $u->to_string($u->create)',
            features => {
                is_xs => 1,
                is_pp => 0,
                create_v1 => 1,
                create_v2 => 1,
                create_v3 => 0,
                create_v4 => 0,
                create_v5 => 0,
            },
        },

        {
            module => 'UUID::FFI',
            description => <<'MARKDOWN',

This module provides access to libuuid via the FFI interface. It can create v1
as well as v4 (random) UUIDs. Note that Data::UUID (XS-based) is faster this
module (FFI-based).

The benchmark code creates 1000+1 v1 string UUIDs.

MARKDOWN
            bench_code_template => 'UUID::FFI->new_time for 1..1000; UUID::FFI->new_time->as_hex',
            features => {
                is_xs => 1,
                is_pp => 0,
                create_v1 => 1,
                create_v2 => 0,
                create_v3 => 0,
                create_v4 => 1,
                v4_secure_random => 0,
                v4_rfc4122 => 1,
                create_v5 => 0,
            },
        },

        {
            module => 'UUID::Tiny',
            description => <<'MARKDOWN',

This module should be your go-to choice if you cannot use an XS module. It can
create v1, v3, v4 UUIDs. However, the random v4 UUIDs are not cryptographically
secure; if you need cryptographically secure random UUIDs, use <pm:Crypt::Misc>.

The benchmark code creates 1000+1 v1 string UUIDs.

See also: <pm:Types::UUID> which is a type library that uses Data::UUID as the
backend.

MARKDOWN
            bench_code_template => 'UUID::Tiny::create_uuid() for 1..1000; UUID::Tiny::uuid_to_string(UUID::Tiny::create_uuid())',
            features => {
                is_xs => 0,
                is_pp => 1,
                create_v1 => 1,
                create_v2 => 0,
                create_v3 => 1,
                create_v4 => 1,
                v4_secure_random => 0,
                v4_rfc4122 => 1,
                create_v5 => 1,
            },
        },

        {
            module => 'UUID::Random',
            description => <<'MARKDOWN',

This module simply uses 32 calls to Perl's C<rand()> to construct each random
hexadecimal digits of the UUID (v4). Not really recommended, since perl's
default pseudo-random generator is neither cryptographically secure nor has 128
bit of entropy. It also does not produce v4 UUIDs that conform to RFC 4122 (no
encoding of variant & version information).

To create a cryptographically secure random UUIDs, use <pm:Crypt::Misc>.

The benchmark code creates 1000+1 v4 string UUIDs.

MARKDOWN
            bench_code_template => 'UUID::Random::generate() for 1..1000; ; UUID::Random::generate()',
            features => {
                is_xs => 0,
                is_pp => 1,
                create_v1 => 0,
                create_v2 => 0,
                create_v3 => 0,
                create_v4 => 1,
                v4_secure_random => 0,
                v4_rfc4122 => 0,
                create_v5 => 0,
            },
        },

        {
            module => 'UUID::Random::PERLANCAR',
            description => <<'MARKDOWN',

Just another implementation of <pm:UUID::Random>.

The benchmark code creates 1000+1 v4 string UUIDs.

MARKDOWN
            features => {
                is_xs => 0,
                is_pp => 1,
                create_v1 => 0,
                create_v2 => 0,
                create_v3 => 0,
                create_v4 => 1,
                v4_secure_random => 0,
                v4_rfc4122 => 1,
                create_v5 => 0,
            },
            functions => {
                generate => {
                    bench_code_template => 'UUID::Random::PERLANCAR::generate() for 1..1000; UUID::Random::PERLANCAR::generate()',
                },
                generate_rfc => {
                    bench_code_template => 'UUID::Random::PERLANCAR::generate_rfc() for 1..1000; UUID::Random::PERLANCAR::generate_rfc()',
                },
            },
        },

        {
            module => 'UUID::Random::Secure',
            description => <<'MARKDOWN',

Just like <pm:UUID::Random>, except it uses <pm:Math::Random::Secure>'s
`irand()` to produce random numbers.

The benchmark code creates 1000+1 v4 string UUIDs.

MARKDOWN
            features => {
                is_xs => 0,
                is_pp => 1,
                create_v1 => 0,
                create_v2 => 0,
                create_v3 => 0,
                create_v4 => 1,
                v4_secure_random => 1,
                v4_rfc4122 => 1,
                create_v5 => 0,
            },
            functions => {
                generate => {
                    bench_code_template => 'UUID::Random::Secure::generate() for 1..1000; UUID::Random::Secure::generate()',
                },
                generate_rfc => {
                    bench_code_template => 'UUID::Random::Secure::generate_rfc() for 1..1000; UUID::Random::Secure::generate_rfc()',
                },
            },
         },

        {
            module => 'Crypt::Misc',
            description => <<'MARKDOWN',

This module from the <pm:CryptX> distribution has a function to create and check
v4 UUIDs.

The benchmark code creates 1000+1 v4 string UUIDs.

MARKDOWN
            bench_code_template => 'Crypt::Misc::random_v4uuid() for 1..1000; Crypt::Misc::random_v4uuid()',
            features => {
                is_xs => 0,
                is_pp => 1,
                create_v1 => 0,
                create_v2 => 0,
                create_v3 => 0,
                create_v4 => 1,
                v4_secure_random => 1,
                v4_rfc4122 => 1,
                create_v5 => 0,
            },
        },

        {
            module => 'UUID',
            description => <<'MARKDOWN',

This module generates DCE-compatible UUIDs, which according to RFC belongs to
the legacy variants.

The benchmark creates 1000+1 random UUIDs.

MARKDOWN
         bench_code_template => 'my $uuid; UUID::generate_random($uuid) for 1..1000; UUID::generate_random($uuid); $uuid',
            features => {
                is_xs => 1,
                is_pp => 0,
                create_v1 => 0,
                create_v2 => 0,
                create_v3 => 0,
                create_v4 => 0,
                v4_secure_random => 0,
                v4_rfc4122 => 0,
                create_v5 => 0,
                create_legacy => 1,
            },
        },

    ],
};

1;
# ABSTRACT: List of modules that can generate immutable universally unique identifier (UUIDs)

__END__

=pod

=encoding UTF-8

=head1 NAME

Acme::CPANModules::UUID - List of modules that can generate immutable universally unique identifier (UUIDs)

=head1 VERSION

This document describes version 0.011 of Acme::CPANModules::UUID (from Perl distribution Acme-CPANModules-UUID), released on 2023-10-30.

=head1 SYNOPSIS

To run benchmark with default option:

 % bencher --cpanmodules-module UUID

To run module startup overhead benchmark:

 % bencher --module-startup --cpanmodules-module UUID

For more options (dump scenario, list/include/exclude/add participants, list/include/exclude/add datasets, etc), see L<bencher> or run C<bencher --help>.

=head1 DESCRIPTION

UUIDs (Universally Unique Identifiers), sometimes also called GUIDs (Globally
Unique Identifiers), are 128-bit numbers that can be used as permanent IDs or
keys in databases. There are several standards that specify UUID, one of which
is RFC 4122 (2005), which we will follow in this document.

UUIDs are canonically represented as 32 hexadecimal digits in the form of:

 xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

There are several variants of UUID. The variant information is encoded using 1-3
bits in the C<N> position. RFC 4122 defines 4 variants (0 to 3), two of which (0
and 3) are for legacy UUIDs, so that leaves variants 1 and 2 as the current
specification.

There are 5 "versions" of UUID for both variants 1 & 2, each might be more
suitable than others in specific cases. The version information is encoded in
the M position. Version 1 (v1) UUIDs are generated from a time and a node ID
(usually the MAC address); version 2 (v2) UUIDs from an identifier (group/user
ID), a time, and a node ID; version 4 (v4) UUIDs from a rando/mpseudo-random
number; version 3 (v3) UUIDs from hashing a namespace using MD5; version 5 (v5)
from hashing a namespace using SHA-1.

L<Data::UUID> should be your first choice, and when you cannot install XS
modules you can use L<UUID::Tiny> instead.

Aside from the modules listed as entries below, there are also:
L<App::UUIDUtils> (containing CLIs to create/check UUID), L<Data::GUID>
(currently just a wrapper for Data::UUID).

=head1 ACME::CPANMODULES ENTRIES

=over

=item L<Data::UUID>

Author: L<RJBS|https://metacpan.org/author/RJBS>

This module creates v1 and v2 UUIDs. Depending on the OS, for MAC address, it
usually uses a hash of hostname instead. This module is XS, so performance is
good. If you cannot use an XS module, try L<UUID::Tiny> instead.

The benchmark code creates 1000+1 v1 string UUIDs.


=item L<UUID::FFI>

Author: L<PLICEASE|https://metacpan.org/author/PLICEASE>

This module provides access to libuuid via the FFI interface. It can create v1
as well as v4 (random) UUIDs. Note that Data::UUID (XS-based) is faster this
module (FFI-based).

The benchmark code creates 1000+1 v1 string UUIDs.


=item L<UUID::Tiny>

Author: L<CAUGUSTIN|https://metacpan.org/author/CAUGUSTIN>

This module should be your go-to choice if you cannot use an XS module. It can
create v1, v3, v4 UUIDs. However, the random v4 UUIDs are not cryptographically
secure; if you need cryptographically secure random UUIDs, use L<Crypt::Misc>.

The benchmark code creates 1000+1 v1 string UUIDs.

See also: L<Types::UUID> which is a type library that uses Data::UUID as the
backend.


=item L<UUID::Random>

Author: L<PERLER|https://metacpan.org/author/PERLER>

This module simply uses 32 calls to Perl's C<rand()> to construct each random
hexadecimal digits of the UUID (v4). Not really recommended, since perl's
default pseudo-random generator is neither cryptographically secure nor has 128
bit of entropy. It also does not produce v4 UUIDs that conform to RFC 4122 (no
encoding of variant & version information).

To create a cryptographically secure random UUIDs, use L<Crypt::Misc>.

The benchmark code creates 1000+1 v4 string UUIDs.


=item L<UUID::Random::PERLANCAR>

Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>

Just another implementation of L<UUID::Random>.

The benchmark code creates 1000+1 v4 string UUIDs.


=item L<UUID::Random::Secure>

Author: L<PERLANCAR|https://metacpan.org/author/PERLANCAR>

Just like L<UUID::Random>, except it uses L<Math::Random::Secure>'s
C<irand()> to produce random numbers.

The benchmark code creates 1000+1 v4 string UUIDs.


=item L<Crypt::Misc>

Author: L<MIK|https://metacpan.org/author/MIK>

This module from the L<CryptX> distribution has a function to create and check
v4 UUIDs.

The benchmark code creates 1000+1 v4 string UUIDs.


=item L<UUID>

Author: L<JRM|https://metacpan.org/author/JRM>

This module generates DCE-compatible UUIDs, which according to RFC belongs to
the legacy variants.

The benchmark creates 1000+1 random UUIDs.


=back

=head1 ACME::CPANMODULES FEATURE COMPARISON MATRIX

 +-------------------------+-----------+-----------+-----------+-----------+-----------+-------+-------+----------------+----------------------+---------------+
 | module                  | create_v1 | create_v2 | create_v3 | create_v4 | create_v5 | is_pp | is_xs | v4_rfc4122 *1) | v4_secure_random *2) | create_legacy |
 +-------------------------+-----------+-----------+-----------+-----------+-----------+-------+-------+----------------+----------------------+---------------+
 | Data::UUID              | yes       | yes       | no        | no        | no        | no    | yes   | N/A            | N/A                  | N/A           |
 | UUID::FFI               | yes       | no        | no        | yes       | no        | no    | yes   | yes            | no                   | N/A           |
 | UUID::Tiny              | yes       | no        | yes       | yes       | yes       | yes   | no    | yes            | no                   | N/A           |
 | UUID::Random            | no        | no        | no        | yes       | no        | yes   | no    | no             | no                   | N/A           |
 | UUID::Random::PERLANCAR | no        | no        | no        | yes       | no        | yes   | no    | yes            | no                   | N/A           |
 | UUID::Random::Secure    | no        | no        | no        | yes       | no        | yes   | no    | yes            | yes                  | N/A           |
 | Crypt::Misc             | no        | no        | no        | yes       | no        | yes   | no    | yes            | yes                  | N/A           |
 | UUID                    | no        | no        | no        | no        | no        | no    | yes   | no             | no                   | yes           |
 +-------------------------+-----------+-----------+-----------+-----------+-----------+-------+-------+----------------+----------------------+---------------+


Notes:

=over

=item 1. v4_rfc4122: Whether the generated v4 UUID follows RFC 4122 specification (i.e. encodes variant and version information in M & N positions)

=item 2. v4_secure_random: Whether the module uses cryptographically secure pseudo-random number generator for v4 UUIDs

=back

=head1 BENCHMARKED MODULES

Version numbers shown below are the versions used when running the sample benchmark.

L<Data::UUID> 1.226

L<UUID::FFI> 0.11

L<UUID::Tiny> 1.04

L<UUID::Random> 0.04

L<UUID::Random::PERLANCAR> 0.005

L<UUID::Random::Secure> 0.004

L<Crypt::Misc> 0.078

L<UUID> 0.29

=head1 BENCHMARK PARTICIPANTS

=over

=item * Data::UUID (perl_code)

Code template:

 my $u = Data::UUID->new; $u->create for 1..1000; $u->to_string($u->create)



=item * UUID::FFI (perl_code)

Code template:

 UUID::FFI->new_time for 1..1000; UUID::FFI->new_time->as_hex



=item * UUID::Tiny (perl_code)

Code template:

 UUID::Tiny::create_uuid() for 1..1000; UUID::Tiny::uuid_to_string(UUID::Tiny::create_uuid())



=item * UUID::Random (perl_code)

Code template:

 UUID::Random::generate() for 1..1000; ; UUID::Random::generate()



=item * UUID::Random::PERLANCAR::generate (perl_code)

Code template:

 UUID::Random::PERLANCAR::generate() for 1..1000; UUID::Random::PERLANCAR::generate()



=item * UUID::Random::PERLANCAR::generate_rfc (perl_code)

Code template:

 UUID::Random::PERLANCAR::generate_rfc() for 1..1000; UUID::Random::PERLANCAR::generate_rfc()



=item * UUID::Random::Secure::generate (perl_code)

Code template:

 UUID::Random::Secure::generate() for 1..1000; UUID::Random::Secure::generate()



=item * UUID::Random::Secure::generate_rfc (perl_code)

Code template:

 UUID::Random::Secure::generate_rfc() for 1..1000; UUID::Random::Secure::generate_rfc()



=item * Crypt::Misc (perl_code)

Code template:

 Crypt::Misc::random_v4uuid() for 1..1000; Crypt::Misc::random_v4uuid()



=item * UUID (perl_code)

Code template:

 my $uuid; UUID::generate_random($uuid) for 1..1000; UUID::generate_random($uuid); $uuid



=back

=head1 BENCHMARK SAMPLE RESULTS

=head2 Sample benchmark #1

Run on: perl: I<< v5.38.0 >>, CPU: I<< Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz (2 cores) >>, OS: I<< GNU/Linux Ubuntu version 20.04 >>, OS kernel: I<< Linux version 5.4.0-164-generic >>.

Benchmark command (default options):

 % bencher --cpanmodules-module UUID

Result formatted as table:

 #table1#
 +---------------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
 | participant                           | rate (/s) | time (ms) | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors   | samples |
 +---------------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+
 | UUID::Random::Secure::generate        |        30 |     30    |                 0.00% |              4218.76% |   0.0013  |      22 |
 | UUID::Random::Secure::generate_rfc    |        40 |     20    |                42.61% |              2928.29% |   0.0003  |      21 |
 | UUID::Random                          |       100 |      9    |               257.90% |              1106.70% |   0.00018 |      20 |
 | UUID::Tiny                            |       100 |      8    |               335.56% |               891.54% |   0.00013 |      20 |
 | UUID                                  |       171 |      5.84 |               481.07% |               643.25% | 1.4e-06   |      21 |
 | Crypt::Misc                           |       296 |      3.37 |               906.43% |               329.12% | 2.6e-06   |      20 |
 | UUID::Random::PERLANCAR::generate_rfc |       520 |      1.9  |              1682.35% |               142.31% | 7.6e-06   |      20 |
 | UUID::Random::PERLANCAR::generate     |       900 |      1    |              2809.14% |                48.45% | 2.5e-05   |      23 |
 | UUID::FFI                             |       870 |      1.2  |              2848.45% |                46.48% | 1.8e-06   |      20 |
 | Data::UUID                            |      1000 |      0.8  |              4218.76% |                 0.00% | 9.3e-06   |      21 |
 +---------------------------------------+-----------+-----------+-----------------------+-----------------------+-----------+---------+


The above result formatted in L<Benchmark.pm|Benchmark> style:

             Rate  URS:g  URS:g_r    U:R   U:T     U   C:M  URP:g_r   U:F  URP:g   D:U 
  URS:g      30/s     --     -33%   -70%  -73%  -80%  -88%     -93%  -96%   -96%  -97% 
  URS:g_r    40/s    50%       --   -55%  -60%  -70%  -83%     -90%  -94%   -95%  -96% 
  U:R       100/s   233%     122%     --  -11%  -35%  -62%     -78%  -86%   -88%  -91% 
  U:T       100/s   275%     150%    12%    --  -27%  -57%     -76%  -85%   -87%  -90% 
  U         171/s   413%     242%    54%   36%    --  -42%     -67%  -79%   -82%  -86% 
  C:M       296/s   790%     493%   167%  137%   73%    --     -43%  -64%   -70%  -76% 
  URP:g_r   520/s  1478%     952%   373%  321%  207%   77%       --  -36%   -47%  -57% 
  U:F       870/s  2400%    1566%   650%  566%  386%  180%      58%    --   -16%  -33% 
  URP:g     900/s  2900%    1900%   800%  700%  484%  237%      89%   19%     --  -19% 
  D:U      1000/s  3650%    2400%  1025%  900%  630%  321%     137%   49%    25%    -- 
 
 Legends:
   C:M: participant=Crypt::Misc
   D:U: participant=Data::UUID
   U: participant=UUID
   U:F: participant=UUID::FFI
   U:R: participant=UUID::Random
   U:T: participant=UUID::Tiny
   URP:g: participant=UUID::Random::PERLANCAR::generate
   URP:g_r: participant=UUID::Random::PERLANCAR::generate_rfc
   URS:g: participant=UUID::Random::Secure::generate
   URS:g_r: participant=UUID::Random::Secure::generate_rfc

=head2 Sample benchmark #2

Benchmark command (benchmarking module startup overhead):

 % bencher --cpanmodules-module UUID --module-startup

Result formatted as table:

 #table2#
 +-------------------------+-----------+-------------------+-----------------------+-----------------------+-----------+---------+
 | participant             | time (ms) | mod_overhead_time | pct_faster_vs_slowest | pct_slower_vs_fastest |  errors   | samples |
 +-------------------------+-----------+-------------------+-----------------------+-----------------------+-----------+---------+
 | UUID::Random::Secure    |     95    |             88.45 |                 0.00% |              1352.22% |   0.00022 |      20 |
 | UUID::FFI               |     53    |             46.45 |                80.85% |               703.01% |   0.00013 |      20 |
 | UUID::Tiny              |     26.7  |             20.15 |               256.48% |               307.38% | 2.3e-05   |      20 |
 | Crypt::Misc             |     20.9  |             14.35 |               354.68% |               219.40% | 1.9e-05   |      20 |
 | Data::UUID              |     20    |             13.45 |               429.95% |               174.03% |   0.00041 |      20 |
 | UUID                    |     11.4  |              4.85 |               734.65% |                73.99% | 5.5e-06   |      20 |
 | UUID::Random            |      8.9  |              2.35 |               962.94% |                36.62% |   1e-05   |      20 |
 | UUID::Random::PERLANCAR |      8.94 |              2.39 |               964.20% |                36.46% | 7.2e-06   |      20 |
 | perl -e1 (baseline)     |      6.55 |              0    |              1352.22% |                 0.00% | 6.3e-06   |      20 |
 +-------------------------+-----------+-------------------+-----------------------+-----------------------+-----------+---------+


The above result formatted in L<Benchmark.pm|Benchmark> style:

                          Rate   UR:S   U:F   U:T   C:M   D:U     U  UR:P   U:R  perl -e1 (baseline) 
  UR:S                  10.5/s     --  -44%  -71%  -78%  -78%  -88%  -90%  -90%                 -93% 
  U:F                   18.9/s    79%    --  -49%  -60%  -62%  -78%  -83%  -83%                 -87% 
  U:T                   37.5/s   255%   98%    --  -21%  -25%  -57%  -66%  -66%                 -75% 
  C:M                   47.8/s   354%  153%   27%    --   -4%  -45%  -57%  -57%                 -68% 
  D:U                   50.0/s   375%  165%   33%    4%    --  -42%  -55%  -55%                 -67% 
  U                     87.7/s   733%  364%  134%   83%   75%    --  -21%  -21%                 -42% 
  UR:P                 111.9/s   962%  492%  198%  133%  123%   27%    --    0%                 -26% 
  U:R                  112.4/s   967%  495%  200%  134%  124%   28%    0%    --                 -26% 
  perl -e1 (baseline)  152.7/s  1350%  709%  307%  219%  205%   74%   36%   35%                   -- 
 
 Legends:
   C:M: mod_overhead_time=14.35 participant=Crypt::Misc
   D:U: mod_overhead_time=13.45 participant=Data::UUID
   U: mod_overhead_time=4.85 participant=UUID
   U:F: mod_overhead_time=46.45 participant=UUID::FFI
   U:R: mod_overhead_time=2.35 participant=UUID::Random
   U:T: mod_overhead_time=20.15 participant=UUID::Tiny
   UR:P: mod_overhead_time=2.39 participant=UUID::Random::PERLANCAR
   UR:S: mod_overhead_time=88.45 participant=UUID::Random::Secure
   perl -e1 (baseline): mod_overhead_time=0 participant=perl -e1 (baseline)

To display as an interactive HTML table on a browser, you can add option C<--format html+datatables>.

=head1 FAQ

=head2 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 L<Acme::CPANModules> for more details.

=head2 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 L<cpanm-cpanmodules> script (from
L<App::cpanm::cpanmodules> distribution):

 % cpanm-cpanmodules -n UUID

Alternatively you can use the L<cpanmodules> CLI (from L<App::cpanmodules>
distribution):

    % cpanmodules ls-entries UUID | cpanm -n

or L<Acme::CM::Get>:

    % perl -MAcme::CM::Get=UUID -E'say $_->{module} for @{ $LIST->{entries} }' | cpanm -n

or directly:

    % perl -MAcme::CPANModules::UUID -E'say $_->{module} for @{ $Acme::CPANModules::UUID::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 L<bencher> CLI (from L<Bencher> distribution):

    % bencher --cpanmodules-module UUID

This Acme::CPANModules module also helps L<lcpan> produce a more meaningful
result for C<lcpan related-mods> command when it comes to finding related
modules for the modules listed in this Acme::CPANModules module.
See L<App::lcpan::Cmd::related_mods> for more details on how "related modules"
are found.

=head1 HOMEPAGE

Please visit the project's homepage at L<https://metacpan.org/release/Acme-CPANModules-UUID>.

=head1 SOURCE

Source repository is at L<https://github.com/perlancar/perl-Acme-CPANModules-UUID>.

=head1 SEE ALSO

L<Acme::CPANModules> - about the Acme::CPANModules namespace

L<cpanmodules> - CLI tool to let you browse/view the lists

RFC 4122, L<https://tools.ietf.org/html/rfc4122>

L<https://en.wikipedia.org/wiki/Universally_unique_identifier>

=head1 AUTHOR

perlancar <perlancar@cpan.org>

=head1 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 L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>,
L<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.

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2023, 2021, 2020 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.

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Acme-CPANModules-UUID>

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.

=cut
