I'm looking for a data structure which should preferably perform equal O(1)? for any number of elements when adding/removing/retrieving elements.
Here are some additional guidelines,
- retrieving elements should not involve slow
keys()
- elements must be always unique and defined
- element order is not significant
- addition or removal of element should not involve iteration over other elements
- gaps in retrieved list of elements are tolerable and can be represented with
undef
value
Please suggest better solution than,
sub uniqArrayFactory {
my $members = [];
my $seen = {};
my $gaps = [];
return sub {
my (%arg) = @_;
return $members if $arg{members};
my $m;
if (defined ($m = $arg{del})) {
return if !$seen->{$m};
${ $seen->{$m} } = undef;
push @$gaps, delete($seen->{$m});
}
elsif (defined ($m = $arg{add})) {
return if $seen->{$m};
if (@$gaps) {
$seen->{$m} = pop @$gaps;
${ $seen->{$m} } = $m;
}
else {
push @$members, $m;
$seen->{$m} = \( $members->[-1] );
}
}
return $m;
};
}
UPDATE (usage)
my $fa = uniqArrayFactory();
$fa->(add => 10);
$fa->(del => 10);
my $members = $fa->(mebers => 1);
keys
performance, and it would get invoked a lot. – Confiscatekeys
operator, which is written in C. I think you need to explain more about what you're doing that is giving you unacceptable performance.keys
is a trivial operation and does little more than return a pre-existing list of C strings reformatted as Perl scalars – Hatbox$members
is faster asreturn [keys %$seen]
. So, if the factory must be very fast for the$factory->(members => 1)
then thekeys
isn't the fastest solution. – Geospherekeys()
and a few flavors ofeach()
) and differences are significant. – Confiscatekeys
andeach
are so slow.for my $v (keys %hash1)
is a bit faster but still considerably slower than your uarray. – Wellbalanced