Michele said:
Let's just say that when you 'return(str)' you return up until the first
NULL is reached. In this case the 21st character is a '1' and the 22nd
character is a NULL. When I started running this on Win32 I sometimes
got 25 characters back before a NULL was reached.
There's no "perhaps" about it - it's definitely what was happening. And
the longer the string, the greater the chance that you'll strike a NULL
before you get that full quota back.
Ditto as above! Many good points IMHO make all this stuff an
interesting case study...
'abigail()' is buggy, non-portable (Win32 doesn't like
'perror(malloc)'), and leaks - though the bugs and portability issue are
easily fixed. (See revised code below.)
'sisyphus2()' despite addressing the "buffer duplication" issue, is
about 4 times slower than 'sisyphus()'. This is because 'sv_insert()' is
slow. Maybe there's a more efficient way of setting the characters of
a SV to random values. If there is, then I couldn't find it, and we'll
have to wait for someone else to tell us about it.
The only changes I've made to 'sisyphus()' and 'sisyphus2()' is to take
values mod 256 (not 255). This means that those 2 subs produce
characters in the range chr(0)..chr(255), whereas 'abigail()' produces
characters in the range chr(1)..chr(255). You can suit yourself in
regard to this - the important thing is that you don't want to let
'abigail()' produce NULL characters.
I've also restored 'l' to the original value of 20000.
Just use the 'sisyphus()' subroutine - which is essentially as I posted
in the first place - unless someone can convince you to do otherwise.
use warnings;
use Benchmark;
use Inline C => Config =>
BUILD_NOISY => 1;
use Inline C => <<'EOC';
char * abigail () {
char * str;
int i;
int l;
l = 20000;
srand (time ((time_t) NULL));
if ((str = (char *) malloc ((l + 1) * sizeof (char))) ==
(char *) NULL) {
croak("Failed to allocate memory in abigail()");
}
for (i = 0; i < l; i ++) {
str
= (rand () % 255) + 1;
}
str[l] = 0;
return (str);
}
SV * sisyphus () {
char * str;
SV * outsv;
int i;
int l;
l = 20000;
srand (time ((time_t) NULL));
New(1, str, l * sizeof(char), char);
if(str == NULL)
croak("Failed to allocate memory in sisyphus()");
for (i = 0; i < l; i ++) {
str = rand () % 256;
}
outsv = newSVpv(str, l);
Safefree(str);
return outsv;
}
SV * sisyphus2 () {
SV * outsv;
char c;
int i;
int l = 20000;
outsv = NEWSV(0, l);
srand (time ((time_t) NULL));
for (i = 0; i < l; i ++) {
c = rand () % 256;
sv_insert(outsv, i, 1, &c, 1);
}
SvPOK_on(outsv);
SvCUR_set(outsv, l);
return outsv;
}
EOC
$s1 = abigail();
print length($s1), "\n";
$s2 = sisyphus();
print length($s2), "\n";
$s3 = sisyphus2();
print length($s3), "\n";
timethese(500, {
's1' => '$s1 = abigail();',
's2' => '$s2 = sisyphus();',
's3' => '$s3 = sisyphus2();',
}),
__END__
Cheers,
Rob