in reply to User Existance?

Well, let's benchmark and see. I created a /etc/passwd file with over 6000 users each named x and some number. Here I search for the user x1, x50, x1000, x3000, and x6000. I test with getpwnam and a regex. Each test is tried 1000 times and the output follows(All tests run on a PII-450 with 384MB RAM running Redhat 9):

#!/usr/bin/perl -w use Benchmark; for $x (1, 50, 1000, 3000, 6000){ timethese (1000,{ "getpwnam${x}" => q { $there=getpwnam("x${x}") }, "regex${x}" => q {open(PASSWD,"/etc/passwd"); while(<PASSWD>) { if (/^x${x}:/){$alsothere=1}; last if $alsothere == 1; } close PASSWD;}, }); } Benchmark: timing 1000 iterations of getpwnam1, regex1... getpwnam1: 0 wallclock secs ( 0.13 usr + 0.05 sys = 0.18 CPU) @ 55 +55.56/s (n=1000) (warning: too few iterations for a reliable count) regex1: 0 wallclock secs ( 0.10 usr + 0.03 sys = 0.13 CPU) @ 76 +92.31/s (n=1000) (warning: too few iterations for a reliable count) Benchmark: timing 1000 iterations of getpwnam50, regex50... getpwnam50: 1 wallclock secs ( 0.29 usr + 0.02 sys = 0.31 CPU) @ 32 +25.81/s (n=1000) (warning: too few iterations for a reliable count) regex50: 0 wallclock secs ( 0.08 usr + 0.05 sys = 0.13 CPU) @ 76 +92.31/s (n=1000) (warning: too few iterations for a reliable count) Benchmark: timing 1000 iterations of getpwnam1000, regex1000... getpwnam1000: 2 wallclock secs ( 2.36 usr + 0.24 sys = 2.60 CPU) @ +384.62/s (n=1000) regex1000: 0 wallclock secs ( 0.10 usr + 0.04 sys = 0.14 CPU) @ 71 +42.86/s (n=1000) (warning: too few iterations for a reliable count) Benchmark: timing 1000 iterations of getpwnam3000, regex3000... getpwnam3000: 8 wallclock secs ( 7.26 usr + 0.43 sys = 7.69 CPU) @ +130.04/s (n=1000) regex3000: 1 wallclock secs ( 0.12 usr + 0.05 sys = 0.17 CPU) @ 58 +82.35/s (n=1000) (warning: too few iterations for a reliable count) Benchmark: timing 1000 iterations of getpwnam6000, regex6000... getpwnam6000: 16 wallclock secs (14.73 usr + 0.67 sys = 15.40 CPU) @ +64.94/s (n=1000) regex6000: 0 wallclock secs ( 0.13 usr + 0.06 sys = 0.19 CPU) @ 52 +63.16/s (n=1000) (warning: too few iterations for a reliable count)

Suprisingly the regex wins hands down. Not too shabby. I don't think you need to worry about your script being slow at all.

HTH

Replies are listed 'Best First'.
Re: Re: User Existance?
by pzbagel (Chaplain) on May 17, 2003 at 18:50 UTC

    I apologize, my while loop exit code was wrong. No wonder the regex beat getpwnam. Here is the correct code and results. Stick wirh getpwnam().

    #!/usr/bin/perl -w use Benchmark; for $x (1, 50, 1000, 3000, 6000){ timethese (1000,{ "getpwnam${x}" => q { $there=getpwnam("x${x}") }, "regex${x}" => q {open(PASSWD,"/etc/passwd"); while(<PASSWD>) { if (/^x${x}:/){$alsothere=1; last}; } close PASSWD;}, }); } Benchmark: timing 1000 iterations of getpwnam1, regex1... getpwnam1: 0 wallclock secs ( 0.12 usr + 0.06 sys = 0.18 CPU) @ 55 +55.56/s (n =1000) (warning: too few iterations for a reliable count) regex1: 0 wallclock secs ( 0.41 usr + 0.02 sys = 0.43 CPU) @ 23 +25.58/s (n =1000) Benchmark: timing 1000 iterations of getpwnam50, regex50... getpwnam50: 1 wallclock secs ( 0.28 usr + 0.02 sys = 0.30 CPU) @ 33 +33.33/s (n =1000) (warning: too few iterations for a reliable count) regex50: 1 wallclock secs ( 0.80 usr + 0.04 sys = 0.84 CPU) @ 11 +90.48/s (n =1000) Benchmark: timing 1000 iterations of getpwnam1000, regex1000... getpwnam1000: 2 wallclock secs ( 2.41 usr + 0.20 sys = 2.61 CPU) @ +383.14/s ( n=1000) regex1000: 9 wallclock secs ( 8.52 usr + 0.13 sys = 8.65 CPU) @ 11 +5.61/s (n= 1000) Benchmark: timing 1000 iterations of getpwnam3000, regex3000... getpwnam3000: 9 wallclock secs ( 7.36 usr + 0.38 sys = 7.74 CPU) @ +129.20/s ( n=1000) regex3000: 28 wallclock secs (24.94 usr + 0.54 sys = 25.48 CPU) @ 39 +.25/s (n=1 000) Benchmark: timing 1000 iterations of getpwnam6000, regex6000... getpwnam6000: 16 wallclock secs (14.44 usr + 0.77 sys = 15.21 CPU) @ +65.75/s (n =1000) regex6000: 50 wallclock secs (49.24 usr + 1.17 sys = 50.41 CPU) @ 19 +.84/s (n=1 000)

    Forgiveness Please.

    Beating myself with a bamboo cane as I speak.

Re: Re: User Existance?
by Anonymous Monk on May 17, 2003 at 18:23 UTC
    Thanks for that. Using the regexp method, how would i apply it to this custom made file:
    user1 user2 user3 user4 user5,pass5,email5,ip5 user5,pass5,email5,ip5 user5,pass5,email5,ip5 user5,pass5,email5,ip5 user5,pass5,email5,ip5
    As you can see, the file varies slightly. So i want the regexp to open up the file (located at /etc/adduser/user.log) and match $username against the first part (userX) of each line. If there is a match, print an error.

    Cheers peeps, The help is massivly appreciated :)
      Probably a better way to do this, but here's one way:

      Update So getpwnam is faster? Ok...

      my $username = "usernamehere"; print "Duplicate!\n" if getpwnam($username);
      my $username = "user1"; while (<DATA>) { chomp; my @info = split ","; foreach (@info) { print "Duplicate!\n" if /\A\Q$username\E\z/ } } __DATA__ user1 user2 user3 user4 user5,pass5,email5,ip5 user5,pass5,email5,ip5 user5,pass5,email5,ip5 user5,pass5,email5,ip5 user5,pass5,email5,ip5
        why am i getting an error when trying to run this?
        if getpwnam($username) { $message = $message.'<p>The Chosen Username Already Exists.</p>'; $found_err = 1; }