http://www.perlmonks.org?node_id=7206

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

OK, what I need to do is generate a random number between 1 and 10
I want to do this to call on a random script number, so that the one script is not being used by many people at onece.
My scripts would be called main1.pl, main2.pl, main3.pl, main4.pl, main5.pl, main6.pl, main7.pl, main8.pl, main9.pl and main10.pl.
I would like to have a script (Let's say start.pl) that would send the user to a random script from the above names.
Inside each script would be the exact same code, just use 10 different scripts to decrease the amount of usage that would be present if I had every user calling on main.pl.
So, all I need is to know how to generate a random number between 1 and 10.
If there is another function to call before getting the random number, please give that to me too
(I mean like with visual basic, you should use "Randomize" before using "Rnd" to get a MUCH random #.

Thanx a lot

Replies are listed 'Best First'.
Re: Random Numbers
by chromatic (Archbishop) on Apr 10, 2000 at 02:59 UTC
    Here's the answer to the direct question: my $script = int(rand(10)) +1; There's no need to give it an initial seed (via srand) in versions later than 5.004.

    However, based on what else you've said, I'd recommend looking into mod_perl (if you run Apache), FastCGI (if you run something else) or ISAPI if you run IIS. Using additional scripts will require separate instances of the Perl interpreter (in the normal case) with additional startup penalties and memory usage. Those are two bugaboos in web programming.

    Mod_perl, and ISAPI avoid the startup penalty by embedding a Perl interpreter in the server process, caching the compiled bytecode, and keeping the script active (but sleeping) until it is needed. FastCGI does something similar.

RE: Random Numbers
by turnstep (Parson) on Apr 10, 2000 at 05:49 UTC

    |If there is another function to call before getting the random
    |number, please give that to me too (I mean like with visual
    |basic, you should use "Randomize" before using "Rnd" to get
    |a MUCH random #.

    You should use the 'srand' function, which only needs to be called once in your program (before any 'rand' commands). Seed it with something like the classic:

    srand(time ^ $$);
    which uses the current time (in seconds since the Epoch) and the PID of the process. Perl, in version 5.004, will actually call srand itself when 'rand' is used and perl does not see a srand. Still, it is always best to call it yourself. For really paranoid ultra-randomness, see Math::TrulyRandom (as well as Math::Random).

    Secondly, what do you mean by decrease the 'usage'? In general, it's actually better to have a single process running, for the abovementioned reasons, as well as others. Consider using 'fork', and having no "start.pl." For low [1] numbers, the system will not really see any difference between 10 people running main.pl, or 10 people each running main1.pl, main2.pl, etc. Either way, it's 10 processes.

    [1] In general, you'd need a LOT of users, a very slow CPU, and a very slow, complex script before this really becomes an issue.

Re: Random Numbers
by jbert (Priest) on Apr 10, 2000 at 18:30 UTC
    Whoah.

    As already said above...unless you are doing things which you don't mention in your post (trying to get around some obscure quotas etc) you *don't* want to be doing what you are trying to do.

    There shouldn't be a problem if ten people are running their own copy of 'main.pl'. Or if there are (due to access to shared resources or whatever) then simply renaming the file is unlikely to get around the problem. If it does, (perhaps due to a locking file based on the name of the script created when the script is run) it is probably better to find out why and remove that limitation in the script.

    Remember - duplicating code == bad. If you find a bug in your script or otherwise improve/change it you have to remember to change every copy of your script. This is the main reason why library code and modules are good. (Note to viewers: the reason for using CGI.pm (or other library module) is not primarily to avoid you writing code, it is to get code that has been tested by lots of people and so is likely to be correct/not insecure.)

Re: Random Numbers
by little_mistress (Monk) on Apr 10, 2000 at 02:55 UTC
RE: Random Numbers
by Keef (Sexton) on Apr 12, 2000 at 00:12 UTC
    This is really unnecessary. A round-robin perl script? I don't think it'd help anything, just create more probs. If you're writitng to data files use flock, running mutipule scripts won't help that problem.
Re: Random Numbers
by Anonymous Monk on Apr 11, 2000 at 05:13 UTC
    Ok, then what about this:
    Will my script keep running at the same speed for every user, even if it was supporting, say, 200 users? (I don't think I'll reach that high, but just a question).
      Not necessarily--but what the other posters have been saying to you is that your process of trying to keep the system load down (by keeping around several identical-but-differently-named copies of your script, then invoking a certain script on a random basis) isn't going to solve the problem.

      You're going to have the same load problems with 10 users running differently-named scripts as you are with 10 users running the same script. The load on the machine is going to be essentially the same, so your method isn't going to work.

      Also, you didn't answer jbert's question: are you doing this because of a shared resource? Having 10 differently-named scripts isn't going to help that, either.

      Is this a CGI script? A mod_perl script? A system tool?

      What you need to do, I think, is to figure out exactly what the problem is--have you, for example, actually experienced a high system load, or are you just thinking that in the future such a high load might exist?

      If you're really having problems with system load, you may need to investigate your algorithm: is there a less-taxing way you can do the same thing? Could you make the machine work less by modifying your code?

      Do some benchmarking and profiling of your code: How do I profile my Perl programs?. If you have an idea where your code may be spending the most part of its time, use Benchmark and investigate alternative algorithms. If you really don't know why it's slow, use Devel::DProf to find out.

      That depends on a few things.
      • Are you talking about 200 hits per second?
      • How many concurrent requests can your web server provide? It'll probably queue the others. Apache by default spawns 4 to 8 listeners.
      • How much memory does your script take?
      • How long does your script take to execute?
      • How long does it take to spawn a new interpreter process versus the time it takes your script to execute?
      We can't answer any of those questions for you, but my opinion is that there are very few answers that make mod_perl or some other persistent interpreter the wrong answer.

      Not to drag the thread on, but if 200 users is your upper limit, you have nothing to worry about. Most scripts get executed so quickly that you would need much more than 200 users hitting the site to get 200 copies of the script running at the same time.

Re: Random Numbers
by Anonymous Monk on Apr 10, 2000 at 03:01 UTC
    what does that "%10" at the end of little_mistress' code do?
      % is the modulo operator. If you're familiar with long division, it gives the remainder. It'll chop off the fractional portion, due to some internal conversion magic.

      (int is probably faster, but TIMTOWTDI). That, and I don't think rand will ever return exactly 10, in this case.

        um you know actually i think your right ... it should be rand(10)%10 and i should have used srand to seed the rand function. But when it comes down to it in most cases what i find is that random enough numbers are enough. And its pretty impossible to get a "truely" random number from a computer. So I dont press the point. I could see however in cases where say you were doing some sort of research to select subjects at random to fill a number of cells. In that case you would want a better random algorhythm, but in most cases ... its really ok to just have a random enough number.