Show quoted text> yes, 1.33 fixed the pod to mention this improvement.
I am very sorry for reopening this but I was too quick to actually consider this fixed. I upgraded to the newest version (1.35) to check if it fixed the issue (and I'm not talking about fixing pod). And I assumed it fixed things because I had a bug in my own testing code prepared especially for pasting in this report. Talk about overzealous... Anyhow.
The main point is the dreaded behaviour of sneakily sorting *everytime* an object *returned* from @{$set} is *ACCESSED* remains in the 1.35 still. So its not about the added cost of sort, its the repeated cost of calling promote that hurts. And the time *doubles* everytime such item from @{$set} is used.
I've prepared an NYTProf analysis of a simple @{$set} case (set_object_bug.pl) and attached it to the report, but the gist of it can be seen here:
for (1..100) {
my $x = 0;
foreach my $item ($lil_set->members()) {
# spent 7.24ms making 100 calls to Set::Object::members, avg 72µs/call
$x += $item;
$x += $item;
$x += $item;
$x += $item;
$x += $item;
}
foreach my $item (@{$lil_set}) {
# spent 2.76ms making 100 calls to Set::Object::__ANON__[Set/Object.pm:750], avg 28µs/call
# spent 312µs making 100 calls to Set::Object::TieArray::FETCHSIZE, avg 3µs/call
$x += $item;
# spent 54.1s making 100000 calls to Set::Object::TieArray::FETCH, avg 541µs/call
$x += $item;
# spent 54.0s making 100000 calls to Set::Object::TieArray::FETCH, avg 540µs/call
$x += $item;
# spent 54.0s making 100000 calls to Set::Object::TieArray::FETCH, avg 540µs/call
$x += $item;
# spent 54.1s making 100000 calls to Set::Object::TieArray::FETCH, avg 541µs/call
$x += $item;
# spent 54.1s making 100000 calls to Set::Object::TieArray::FETCH, avg 541µs/call
# spent 380ms making 100000 calls to Set::Object::TieArray::FETCHSIZE, avg 4µs/call
}
Please note the number of calls it is causing. The severity is IMHO high here - it will cause "shadow" performance leaks when using the convenience form. Everytime the item is accessed (FETCH), it will call promote() which in turn is sorting the set, leading to the cases like we recently had, where the total time spent was reduced from 1136s to 0.236s (!) after changing from @{$some_set} to $some_set->members().
So once again, the problem is not the fact that @{$set} is sorting, the problem is it is sorting everytime its items are accessed in foreach or similar.
Last but not least, let's see what actually comes out of @{$set} as opposed to $set->members:
$ cat peek.pl
#!/bin/env perl
use strict; use warnings; use 5.010;
use Set::Object 1.35 qw/set/;
use Devel::Peek;
my $set = set(qw/a/);
say "\$set->members form:";
say Dump($_) foreach $set->members();
say "\n\n\n\@{\$set} form:";
print Dump($_) foreach @{$set};
__END__
$set->members form:
SV = PV(0x228eb78) at 0x2290b98
REFCNT = 2
FLAGS = (POK,pPOK)
PV = 0x22a9830 "a"\0
CUR = 1
LEN = 8
@{$set} form:
SV = PVLV(0x22ef0c0) at 0x23f2910
REFCNT = 2
FLAGS = (GMG,SMG,RMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x22f5040
MG_VIRTUAL = &PL_vtbl_packelem
MG_TYPE = PERL_MAGIC_tiedelem(p)
MG_FLAGS = 0x02
REFCOUNTED
MG_OBJ = 0x243abf0
SV = RV(0x243ac00) at 0x243abf0
REFCNT = 2
FLAGS = (ROK)
RV = 0x22cdda8
SV = PVAV(0x2291f40) at 0x22cdda8
REFCNT = 1
FLAGS = (OBJECT)
STASH = 0x234f8c0 "Set::Object::TieArray"
ARRAY = 0x22d3720
FILL = 1
MAX = 1
ARYLEN = 0x0
FLAGS = (REAL)
Elt No. 0
SV = RV(0x22c8ac8) at 0x22c8ab8
REFCNT = 1
FLAGS = ()
Elt No. 1
SV = RV(0x22cde30) at 0x22cde20
REFCNT = 1
FLAGS = (ROK,WEAKREF)
RV = 0x2290fa0
SV = PVMG(0x22d5890) at 0x2290fa0
REFCNT = 1
FLAGS = (OBJECT,RMG,IOK,OVERLOAD,pIOK)
IV = 36500688
NV = 0
PV = 0
MAGIC = 0x243b680
MG_VIRTUAL = &PL_vtbl_backref
MG_TYPE = PERL_MAGIC_backref(<)
MG_FLAGS = 0x02
REFCOUNTED
MG_OBJ = 0x23f27d8
SV = PVAV(0x23f02f0) at 0x23f27d8
REFCNT = 2
FLAGS = ()
ARRAY = 0x22bb0e0
FILL = 0
MAX = 3
ARYLEN = 0x0
FLAGS = ()
STASH = 0x22cdc58 "Set::Object"
TYPE = t
TARGOFF = 0
TARGLEN = 0
TARG = 0x23f2910
We're using PERL 5.10.1. Maybe the problem is not so severe on newer ones, I don't have a testing environment prepared to test that, alas.