Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Fast random string generation
I need to generate a string of random characters, say about 20,000
characters long. And I need to do it quickly! I tried the obvious:

for( my $i=0; $i<20000; $i++ ) {
$str .= chr(int(rand(256)));
}

which works, but I have a feeling there must be a faster way than doing
20,000 string concatenations...?

Report this thread to moderator Post Follow-up to this message
Old Post
Derek Fountain
10-24-04 08:55 AM


Re: Fast random string generation
"Derek Fountain"  wrote in message
> I need to generate a string of random characters, say about 20,000
> characters long. And I need to do it quickly! I tried the obvious:
>
>     for( my $i=0; $i<20000; $i++ ) {
>       $str .= chr(int(rand(256)));
>     }
>
> which works, but I have a feeling there must be a faster way than doing
> 20,000 string concatenations...?

If speed actually matters (which it may not), you'll have to benchmark this
solution, comparing it to yours.  They may turn out to be reasonably close
to each other in speed.

my $string = join '', map { chr int rand(256) } 1 .. 20_000;

Here's another solution that pre-generates the 'chr' possibilities, and
thus, MAY be a little more efficient.

my @characters = map { chr $_ } 0 .. 255;
my $string = join '', map { $characters[ rand 256 ] } 1 .. 20_000;

Dave




Report this thread to moderator Post Follow-up to this message
Old Post
Dave Oswald
10-24-04 08:55 AM


Re: Fast random string generation
Derek Fountain wrote:

> I need to generate a string of random characters, say about 20,000
> characters long. And I need to do it quickly! I tried the obvious:
>
>     for( my $i=0; $i<20000; $i++ ) {
>       $str .= chr(int(rand(256)));
>     }
>
> which works, but I have a feeling there must be a faster way than doing
> 20,000 string concatenations...?

I didn't benchmark, but I would guess it's faster to call chr() 256
times instead of 20000 times:

# untested code
my @list = map chr, 0 .. 256;
my $str  = '';
$str    .= $list[rand @list] for 1 .. 20_000;

--Ala


Report this thread to moderator Post Follow-up to this message
Old Post
Ala Qumsieh
10-24-04 08:55 AM


Re: Fast random string generation
Derek Fountain <nospam@example.com> wrote:

> I need to generate a string of random characters, say about
> 20,000 characters long. And I need to do it quickly! I tried the
> obvious:
>
>     for( my $i=0; $i<20000; $i++ ) {
>       $str .= chr(int(rand(256)));
>     }
>
> which works, but I have a feeling there must be a faster way
> than doing 20,000 string concatenations...?

my $str = "\000" x 20_000;
my @chr = map { chr $_ } 0 .. 255;
substr $str, $_, 1, $chr[rand 256] for 1 .. 20_000;

Peter

--
#!/local/bin/perl5 -wp -*- mode: cperl; coding: iso-8859-1; -*-
# matlab comment stripper (strips comments from Matlab m-files)
s/^((?:(?:[])}\w.]'+|[^'%])+|'[^'\n]*(?:''[^'\n]*)*')*).*/$1/x;

Report this thread to moderator Post Follow-up to this message
Old Post
Peter J. Acklam
10-24-04 08:56 PM


Re: Fast random string generation
Derek Fountain (nospam@example.com) wrote on MMMMLXXII September MCMXCIII
in <URL:news:417b232b$0$13761$5a62ac22@per-qv1-newsreader-01.iinet.net.au>:
<>  I need to generate a string of random characters, say about 20,000
<>  characters long. And I need to do it quickly! I tried the obvious:
<>
<>      for( my $i=0; $i<20000; $i++ ) {
<>        $str .= chr(int(rand(256)));
<>      }
<>
<>  which works, but I have a feeling there must be a faster way than doing
<>  20,000 string concatenations...?


Write it in C.


#!/usr/bin/perl

use strict;
use warnings;
no warnings qw /syntax/;

use Inline 'C';

sub r_string;

print r_string (20_000), "\n";

__END__
__C__
char * r_string (int l) {
char * str;
int    i;

srand (time ((time_t) NULL));
if ((str = (char *) malloc (l * sizeof (char))) == (char *) NULL) {
perror (malloc);
exit (-1);
}
for (i = 0; i < l; i ++) {
str [i] = rand () % 255;
}
return (str);
}
--
sub f{sprintf'%c%s',$_[0],$_[1]}print f(74,f(117,f(115,f(116,f(32,f(97,
 f(110,f(111,f(116,f(104,f(0x65,f(114,f(3
2,f(80,f(101,f(114,f(0x6c,f(32,
 f(0x48,f(97,f(99,f(107,f(101,f(114,f(10,
q ff)))))))))))))))))))))))))

Report this thread to moderator Post Follow-up to this message
Old Post
Abigail
10-25-04 01:55 AM


Re: Fast random string generation
Ala Qumsieh wrote:

>I didn't benchmark, but I would guess it's faster to call chr() 256
>times instead of 20000 times:
>
>    # untested code
>    my @list = map chr, 0 .. 256;
>    my $str  = '';
>    $str    .= $list[rand @list] for 1 .. 20_000;

It's also not very random. I don't think it's the idea to have a repeat
period of 256 cycles.

--
Bart.

Report this thread to moderator Post Follow-up to this message
Old Post
Bart Lateur
10-25-04 08:58 AM


Re: Fast random string generation
Derek Fountain wrote:

>I need to generate a string of random characters, say about 20,000
>characters long. And I need to do it quickly! I tried the obvious:
>
>    for( my $i=0; $i<20000; $i++ ) {
>      $str .= chr(int(rand(256)));
>    }
>
>which works, but I have a feeling there must be a faster way than doing
>20,000 string concatenations...?

I have the following basic 3 ideas:

1) prebuild a string of 20000 bytes, and use substr to replace the
concatenation:

$x = " " x 20000;
substr($x, $_, 1) = chr rand 256 for 0 .. 19999;


2) ditto, but use vec() (bypasses chr()):

$x = " " x 20000;
vec($x, $_, 8) = rand 256 for 0 .. 19999;


3) use pack 'C*' to replace all of the chr() calls + concat/join:

$x = pack 'C*', map int rand 256, 1 .. 20000;

--
Bart.

Report this thread to moderator Post Follow-up to this message
Old Post
Bart Lateur
10-25-04 01:56 PM


Re: Fast random string generation
Bart Lateur wrote:
> Ala Qumsieh wrote:
>
> 
>
>
> It's also not very random. I don't think it's the idea to have a repeat
> period of 256 cycles.

Neither suggestion does.

--
John W. Kennedy
"The poor have sometimes objected to being governed badly; the rich have
always objected to being governed at all."
-- G. K. Chesterton.  "The Man Who Was Thursday"

Report this thread to moderator Post Follow-up to this message
Old Post
John W. Kennedy
10-25-04 09:00 PM


Re: Fast random string generation
On Sun, 24 Oct 2004 11:38:30 +0800, Derek Fountain
<nospam@example.com> wrote:

>I need to generate a string of random characters, say about 20,000
>characters long. And I need to do it quickly! I tried the obvious:

OK, here are the benchmarks of some of the proposed solutions along
with some other idea.

BTW: I'm to say the least in a rush and I could absoultely NOT verify
that my 'Pack2' solution is correct. But in case it is notm then I
guess that it can be easily corrected.

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark qw/:all/;

cmpthese 500, {
Loop1 => \&Loop1,
Loop2 => \&Loop2,
Map1 => \&Map1,
Map2 => \&Map2,
Subst => \&Subst,
Vec => \&Vec,
Pack1 => \&Pack1,
Pack2 => \&Pack2,
S => \&S
};


sub Loop1 {
my $str = '';
$str .= chr int rand 256 for 1..20_000;
$str;
}

sub Loop2 {
my @chrs = map chr, 0..255;
my $str = '';
$str .= $chrs[rand 256] for 1..20_000;
$str;
}

sub Map1 {
join '', map { chr int rand 256 } 1..20_000;
}

sub Map2 {
my @chrs = map chr, 0..255;
join '', map $chrs[rand 256], 1..20_000;
}

sub Subst {
my $str = "\000" x 20_000;
my @chrs = map chr, 0..255;
substr $str, $_, 1, $chrs[rand 256] for 0..19_999;
$str;
}

sub Vec {
my $str = ' ' x 20000;
vec($str, $_, 8) = rand 256 for 0..19_999;
$str;
}

sub Pack1 {
pack 'C*', map int rand 256, 1..20_000;
}

sub Pack2 {
# Is this OK, BTW?
pack 'L*', map rand ~0, 1..5_000;
}

sub S {
local $_ = ' ' x 20_000;
s/ /chr int rand 256/ge;
$_;
}

__END__


Rate  Map2  Map1     S Subst   Vec Pack1 Loop1 Loop2 Pack2
Map2  47.8/s    --   -1%   -5%  -32%  -36%  -39%  -44%  -48%  -84%
Map1  48.3/s    1%    --   -4%  -32%  -35%  -38%  -43%  -47%  -84%
S     50.2/s    5%    4%    --  -29%  -33%  -36%  -41%  -45%  -84%
Subst 70.6/s   48%   46%   41%    --   -5%   -9%  -17%  -22%  -77%
Vec   74.6/s   56%   54%   49%    6%    --   -4%  -12%  -18%  -76%
Pack1 78.0/s   63%   61%   55%   10%    5%    --   -8%  -14%  -75%
Loop1 84.7/s   77%   75%   69%   20%   14%    9%    --   -7%  -72%
Loop2 91.1/s   91%   89%   81%   29%   22%   17%    7%    --  -70%
Pack2  307/s  542%  535%  511%  334%  311%  293%  262%  237%    --


Any correction/cmt/etc. welcome!


HTH,
Michele
--
 {$_=pack'B8'x25,unpack'A8'x32,$a^=sub{po
p^pop}->(map substr
(($a||=join'',map--$|x$_,(unpack'w',unpack'u','G^<R<Y]*YB='
.'KYU;*EVH[.FHF2W+#"\Z*5TI/ER<Z`S(G.DZZ9OX0Z')=~/./g)x2,$_,
256),7,249);s/[^\w,]/ /g;$ \=/^J/?$/:"\r";print,redo}#JAPH,

Report this thread to moderator Post Follow-up to this message
Old Post
Michele Dondi
10-25-04 09:00 PM


Re: Fast random string generation
Michele Dondi wrote:

>  sub Pack2 {
>      # Is this OK, BTW?
>      pack 'L*', map rand ~0, 1..5_000;
>  }

I don't think you'll ever see "\xFF\xFF\xFF\xFF" there. Better add 1 to
it.

--
Bart.

Report this thread to moderator Post Follow-up to this message
Old Post
Bart Lateur
10-25-04 09:00 PM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

PERL Miscellaneous archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 03:58 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.