Friday, November 26, 2010

Benchmark of UUID generation with Perl

At work the topic of UUID generation came up and our current solution with Data::UUID was too slow.

My initial thoughts were "there must exist a XS module for that". A colleague suggested OSSP uuid. On CPAN I found some more.


use strict;
use warnings;

use Benchmark qw/cmpthese/;
use Data::UUID ();
use Data::UUID::LibUUID ();
use OSSP::uuid qw/:all/;
use UUID ();

my %bench = (
    data_uuid => \&data_uuid,
    libuuid   => \&libuuid,
    ossp      => \&ossp,
    uuid      => \&uuid,

foreach my $name (sort keys %bench) {
    printf("%10s: %s\n", $name, $bench{$name}->());
print "\n";

cmpthese($ARGV[0] || 100_000, \%bench);

sub data_uuid {
    return Data::UUID->new->create_str;

sub libuuid {
    return Data::UUID::LibUUID::new_uuid_string;

sub ossp {
    my ($uuid, $string);
    uuid_make($uuid, UUID_MAKE_V1);
    uuid_export($uuid, UUID_FMT_STR, $string, undef);
    return $string;

sub uuid {
    my ($uuid, $string);
    UUID::unparse($uuid, $string);
    return $string;

The results are overwhelming and show a clear winner (and loser):

> perl
 data_uuid: 69F84998-F99F-11DF-B54E-5B24670C5CFA
   libuuid: 69f8a03c-f99f-11df-b8e9-0019db688fc2
      ossp: 69f8a672-f99f-11df-84f9-0019db688fc2
      uuid: 21795165-7d69-42fd-88f5-6f03c27bb595

              Rate data_uuid      ossp   libuuid      uuid
data_uuid   3189/s        --      -93%      -96%      -98%
ossp       46729/s     1365%        --      -40%      -71%
libuuid    78125/s     2350%       67%        --      -52%
uuid      161290/s     4958%      245%      106%        --

So, expect some changes next week... :)


  1. Looks like the UUID module on CPAN could use a little love, since the very latest shows up as 'unauthorized' and seems to skip a lot of platforms when running tests.

    UUID tests very fast, but are there any drawbacks to this module and the way it generates UUIDs do we think?

  2. Yeah, you are right. Also, I do not like the top level namespace.

    Data::UUID (and ::LibUUID) are more flexible and allow more types and formats. A quick look at the source codes of UUID.xs and LibUUID.xs shows that both are using uuid_generate() of libuuid.

  3. I have some new insights: Data::UUID is much faster when you reuse the object. Actually, DESTROY is taking the most time. :)

    I will publish a follow up post next year, when I finished the Perl-Uwe Advent calendar.

  4. Why is only the output shows `uuid` implementation testing UUID version 4 (random) while others testing UUID version 1 (MAC address)? check the byte after the 2nd '-'

    1. You are right - good catch. It was not done on purpose - I just didn't know better.

  5. Loading this page I get a javascript alert "SyntaxHighlighter: Can't find brush for: Perl".

    1. Thanks, John. I fixed it (and now syntax-highlighting is also back).