bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Bug/limitation in 'time'


From: Bruce Dawson
Subject: RE: Bug/limitation in 'time'
Date: Sat, 16 Mar 2013 19:33:43 -0700

Thanks -- good to know that there is a fast and POSIX compliant method of
doing this. I should have included my optimized counting loop -- it's what
we switched to when we realized that $(expr) was a problem. Here it is now:

# This code performs quite well
function BashCount() {
        i=$1
        while [ $i -gt 0 ]; do
                (( i-- ))
        done
        echo Just did $1 iterations using bash math
}
time BashCount 150000

It's a *lot* faster, of course. BTW, I've poked around in the 'time' source
code enough to know that it is just displaying the results of wait3(), so
the misleading CPU consumption information is ultimately a wait3()/kernel
issue. However showing this in the documentation would be great.

-----Original Message-----
From: Chris F.A. Johnson [mailto:chris@cfajohnson.com] 
Sent: Saturday, March 16, 2013 7:16 PM
To: bug-bash@gnu.org
Cc: Chris Down; Bruce Dawson
Subject: Re: Bug/limitation in 'time'

On Sun, 17 Mar 2013, Chris Down wrote:

> Hi Bruce,
>
> On 2013-03-16 17:41, Bruce Dawson wrote:
>> I think it's important because when I hit this problem (using $(expr) 
>> for looping in shell scripts is slow) I initially assumed that my 
>> task was not CPU bound, because that is what 'time' told me. This 
>> then led me down the wrong path in my investigation.
>
> No comment on the issue itself, but this is just not a good way of 
> writing bash arithmetic loops:
>
>> #!/bin/bash
>> # Warning: this code is excessively slow function ExprCount() {
>>                 i=$1
>>                 while [ $i -gt 0 ]; do
>>                                 i=$(expr $i - 1)
>>                                 #sleep 0.001
>>                 done
>>                 echo Just did $1 iterations using expr math } time 
>> ExprCount 1000
>
> You're forking 1000 subshells for `expr' when you can quite easily do 
> it on your current shell. A better way would be to write it like this:
>
>    ExprCount() {
>        for (( i = $1 ; i > 0 ; i-- )); do
>            :
>        done
>        echo "$1 iterations"
>    }

    Or, in a POSIX-compliant manner:

ExprCount() {
   i=$1
   while [ $(( i -= 1 )) -ge 0 ]; do
     :
   done
   echo Just did $1 iterations using expr math }

-- 
    Chris F.A. Johnson, <http://cfajohnson.com/>
    Author:
    Pro Bash Programming: Scripting the GNU/Linux Shell (2009, Apress)
    Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]