Data::YUID::Generator が 32bit でも動くように Math::BigInt 使ってみた。
ベンチマーク。new() が遅い。
# new->get_id Rate bigint original bigint 2635/s -- -95% original 51945/s 1872% -- # get_id Rate bigint original bigint 79591/s -- -70% original 267101/s 236% --
--- Generator.pm.orig 2009-05-27 13:21:21.000000000 +0900 +++ Generator.pm 2009-05-27 13:53:50.000000000 +0900 @@ -1,6 +1,6 @@ # $Id: Generator.pm 1 2007-12-19 22:39:22Z miyagawa $ -package Data::YUID::Generator; +package Data::YUID::Generator::BigInt; use strict; use warnings; no warnings qw(deprecated); # for fields @@ -8,6 +8,7 @@ use vars qw{$VERSION}; $VERSION = "0.01"; +use Math::BigInt lib => "GMP"; use fields qw(host_id start_time current_time min_id max_id ids); use constant EPOCH_OFFSET => 946684800; # Sat, Jan 1 2000 00:00 GMT @@ -19,17 +20,17 @@ use constant TIME_SHIFT => HOST_ID_BITS + SERIAL_BITS; use constant SERIAL_SHIFT => HOST_ID_BITS; -use constant SERIAL_INCREMENT => 1 << SERIAL_SHIFT; +use constant SERIAL_INCREMENT => Math::BigInt->new(1) << SERIAL_SHIFT; -use constant HOST_ID_MAX => (1 << HOST_ID_BITS) - 1; -use constant TIME_MAX => (1 << TIME_BITS) - 1; +use constant HOST_ID_MAX => (Math::BigInt->new(1) << HOST_ID_BITS) - 1; +use constant TIME_MAX => (Math::BigInt->new(1) << TIME_BITS) - 1; use constant TIME_MAX_SHIFTED => TIME_MAX << TIME_SHIFT; -use constant SERIAL_MAX => (1 << SERIAL_BITS) - 1; +use constant SERIAL_MAX => (Math::BigInt->new(1) << SERIAL_BITS) - 1; use constant SERIAL_MAX_SHIFTED => SERIAL_MAX << SERIAL_SHIFT; sub new { - my Data::YUID::Generator $self = shift; + my Data::YUID::Generator::BigInt $self = shift; $self = fields::new( $self ) unless ref $self; my $host_id = shift; @@ -63,7 +64,7 @@ sub _make_id ($) { my $self = shift; my $serial = shift || 0; - return (($self->{ current_time } - EPOCH_OFFSET) << TIME_SHIFT) | + return ( Math::BigInt->new($self->{ current_time } - EPOCH_OFFSET) << TIME_SHIFT) | ($serial << SERIAL_SHIFT) | $self->{ host_id }; }