in reply to Upper case and chomp

As documented in chomp,
It returns the total number of characters removed from all its arguments.
This means you are using that incorrectly. Rather than using eq, I would suggest using a regular expression, like

my @listaccountlocked = split("=", $accountlocked); if ($listaccountlocked[1] =~ /^true$/i) { system("chuser account_locked='false' $username"); print(`lsuser -a account_locked $username`); } else { print("\nThe account $username is not locked\n\n"); }
where $ will ignore a trailing newline in reporting a match.

Replies are listed 'Best First'.
Re^2: Upper case and chomp
by roboticus (Chancellor) on Feb 10, 2011 at 15:22 UTC

    I prefer using uc and a string compare like the OP suggested. I did a quick benchmark, and it looks like it's faster (negligible if no strings match, roughly double the speed if they all match.

    if (uc($listaccountlocked[1]) eq 'TRUE) {

    Trivial benchmark:

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      You have not used a fair test: note that my regular expression included the Metacharacters ^ and $. If I reconfigure your tests to consider this factor and swap to:
      sub regex { my $cnt=0; for (@words) { ++$cnt if /^abcb$/i; } return $cnt; }
      I get the output:

      In 4096 words, 16 are 'abcb' Rate uccmp regex uccmp 1192/s -- -5% regex 1255/s 5% -- In 4096 words, 0 are 'abcb' Rate uccmp regex uccmp 1225/s -- -3% regex 1264/s 3% -- In 4096 words, 4096 are 'abcb' Rate regex uccmp regex 970/s -- -23% uccmp 1260/s 30% --

      which obviously compares much better. This still does not consider that the string compare require a chomp which the regular expression does not. Modifying your benchmark to consider this:

      yields the results:
      In 4096 words, 16 are 'abcb' Rate uccmp regex uccmp 812/s -- -32% regex 1197/s 47% -- In 4096 words, 0 are 'abcb' Rate uccmp regex uccmp 861/s -- -31% regex 1255/s 46% -- In 4096 words, 4096 are 'abcb' Rate uccmp regex uccmp 856/s -- -11% regex 964/s 13% --
      which I think clearly favors the regular expression. In addition, if you really wanted to squeeze out performance, you could skip the split in the OP as well: which yields:
      In 4096 words, 16 are 'abcb' Rate uccmp regex uccmp 200/s -- -74% regex 767/s 283% -- In 4096 words, 0 are 'abcb' Rate uccmp regex uccmp 200/s -- -74% regex 756/s 278% -- In 4096 words, 4096 are 'abcb' Rate uccmp regex uccmp 206/s -- -66% regex 603/s 193% --

      Update: As ikegami points out, I failed to localize the arrays to the test routines, so there were a large number of no-ops. Fixing that with the code my @words = @words added where appropriate reduced margins but maintained ordering. I suspect that is just a function of the linear overhead of copying the large arrays. If this is incorrect, I would appreciate insight.

        Still bad. After the first pass, there is nothing left to chomp. You need to add my @words = @words; to the start of both functions.

        kennethk:

        I'm sorry I misrepresented your test. I didn't even think about the effect of adding the anchors. Oh, well. Thankfully, you were able to get things fixed up with ikegami, so we now have a better comparison.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

      Another option is string escapes:

      if ("\U$listaccountlocked[1]" eq 'TRUE') {

      I added another sub to your benchmark:

      sub slashU { my $cnt=0; for (@words){ ++$cnt if "\U$_" eq 'ABCB'; } return $cnt; }

      But it didn't fare very well:

      In 4096 words, 16 are 'abcb' Rate slashU uccmp regex slashU 321/s -- -18% -26% uccmp 390/s 21% -- -10% regex 435/s 36% 12% -- In 4096 words, 0 are 'abcb' Rate slashU uccmp regex slashU 328/s -- -17% -25% uccmp 397/s 21% -- -10% regex 439/s 34% 11% -- In 4096 words, 4096 are 'abcb' Rate regex slashU uccmp regex 266/s -- -6% -18% slashU 282/s 6% -- -13% uccmp 325/s 22% 15% --

      Ah well.

        if ("\U$listaccountlocked[1]" eq 'TRUE') {
        is just an obfuscated way of writing
        if (uc($listaccountlocked[1]) eq 'TRUE') {

        From a performance point of view, the former is a proper subset of the latter. Not only does \U calls uc(), it creates an extra copy of the string.

        $ perl -MO=Concise,-exec -e'my $y = "\U$x";' 1 <0> enter 2 <;> nextstate(main 1 -e:1) v:{ 3 <$> gvsv(*x) s 4 <1> uc[t2] sK/1 5 <@> stringify[t3] sK/1 <--- This addition is the only 6 <0> padsv[$y:1,2] sRM*/LVINTRO difference. It creates a 7 <2> sassign vKS/2 copy of the string. 8 <@> leave[1 ref] vKP/REFC -e syntax OK $ perl -MO=Concise,-exec -e'my $y = uc($x);' 1 <0> enter 2 <;> nextstate(main 1 -e:1) v:{ 3 <$> gvsv(*x) s 4 <1> uc[t2] sK/1 5 <0> padsv[$y:1,2] sRM*/LVINTRO 6 <2> sassign vKS/2 7 <@> leave[1 ref] vKP/REFC -e syntax OK