Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista - FYI: 'continue' in 'for' loops is VERY slow

Reply
 
Old 04-03-2007   #1 (permalink)
Roman Kuzmin


 
 

FYI: 'continue' in 'for' loops is VERY slow

Recently I have slightly refactored a script and noticed drastically
improved performance. It turned out that 'continue' in 'for' loop is VERY
slow, in my case it used to take much more time than what a loop body should
actually do.

Example:

> time { for($e=0; ; ++$e) { if ($e -ge 1000) { break } } }

TotalMilliseconds : 10.8296

> time { for($e=0; ; ++$e) { if ($e -ge 1000) { break } else {
> continue } } }

TotalMilliseconds : 170.6035

Can anybody repro\confirm this?

--
Thanks,
Roman Kuzmin



My System SpecsSystem Spec
Old 04-04-2007   #2 (permalink)
Duncan Smith


 
 

Re: FYI: 'continue' in 'for' loops is VERY slow


> Recently I have slightly refactored a script and noticed drastically
> improved performance. It turned out that 'continue' in 'for' loop is VERY
> slow, in my case it used to take much more time than what a loop body should
> actually do.
>
> Example:
>
> > time { for($e=0; ; ++$e) { if ($e -ge 1000) { break } } }

>
> TotalMilliseconds : 10.8296
>
> > time { for($e=0; ; ++$e) { if ($e -ge 1000) { break } else {
> > continue } } }

>
> TotalMilliseconds : 170.6035
>
> Can anybody repro\confirm this?
>


Yes, it's about 20x slower for me too. Is continue an expensive
statement in other languages too such as C++? Can't say I've ever
noticed it. Does Powershell compile script blocks down to IL? I
guess you've maybe got anther script-block around the continue that
needs to be entered into, unless it's optimized away?

function time
{
[datetime]$startTime = [datetime]::now

for($e=0; ; ++$e)
{
if ($e -ge 1000)
{
break
}
}

[datetime]$endTime = [datetime]::now
($endTime - $startTime).TotalSeconds
}

function time2
{
[datetime]$startTime = [datetime]::now

for($e=0; ; ++$e)
{
if ($e -ge 1000)
{
break
}
else
{
continue
}
}

[datetime]$endTime = [datetime]::now
($endTime - $startTime).TotalSeconds

}

0.01 v 0.2

My System SpecsSystem Spec
Old 04-04-2007   #3 (permalink)
Ryan Milligan


 
 

Re: FYI: 'continue' in 'for' loops is VERY slow

If I had to guess, I'd say it's because continue, break and return are all
implemented by throwing exceptions which are caught and handled by the
Execute() method of whichever loop control mechanism (e.g.,
Parser+DoWhileStatementNode in System.Management.Automation.dll) is running
the loop. You can see it by opening System.Management.Automation.dll (in
your Framework\v2.0.50727 folder on XP) in Reflector
(http://www.aisto.com/roeder/dotnet/) and taking a look at
Parser+FlowControlNode.Execute(). Hope this helps.

-- Ryan Milligan

"Duncan Smith" <DSmith1974@googlemail.com> wrote in message
news:1175712048.596748.86350@l77g2000hsb.googlegroups.com...
>
>> Recently I have slightly refactored a script and noticed drastically
>> improved performance. It turned out that 'continue' in 'for' loop is VERY
>> slow, in my case it used to take much more time than what a loop body
>> should
>> actually do.
>>
>> Example:
>>
>> > time { for($e=0; ; ++$e) { if ($e -ge 1000) { break } } }

>>
>> TotalMilliseconds : 10.8296
>>
>> > time { for($e=0; ; ++$e) { if ($e -ge 1000) { break } else {
>> > continue } } }

>>
>> TotalMilliseconds : 170.6035
>>
>> Can anybody repro\confirm this?
>>

>
> Yes, it's about 20x slower for me too. Is continue an expensive
> statement in other languages too such as C++? Can't say I've ever
> noticed it. Does Powershell compile script blocks down to IL? I
> guess you've maybe got anther script-block around the continue that
> needs to be entered into, unless it's optimized away?
>
> function time
> {
> [datetime]$startTime = [datetime]::now
>
> for($e=0; ; ++$e)
> {
> if ($e -ge 1000)
> {
> break
> }
> }
>
> [datetime]$endTime = [datetime]::now
> ($endTime - $startTime).TotalSeconds
> }
>
> function time2
> {
> [datetime]$startTime = [datetime]::now
>
> for($e=0; ; ++$e)
> {
> if ($e -ge 1000)
> {
> break
> }
> else
> {
> continue
> }
> }
>
> [datetime]$endTime = [datetime]::now
> ($endTime - $startTime).TotalSeconds
>
> }
>
> 0.01 v 0.2
>



My System SpecsSystem Spec
Old 04-06-2007   #4 (permalink)
Roman Kuzmin


 
 

Re: FYI: 'continue' in 'for' loops is VERY slow

If so, it looks quite dirty... and I hope this approach is temporary.

--
Thanks,
Roman Kuzmin


My System SpecsSystem Spec
Old 04-06-2007   #5 (permalink)
Duncan Smith


 
 

Re: FYI: 'continue' in 'for' loops is VERY slow

On Apr 4, 10:28 pm, "Ryan Milligan" <Cei...@hotmail.com> wrote:
> If I had to guess, I'd say it's because continue, break and return are all
> implemented by throwing exceptions which are caught and handled by the
> Execute() method of whichever loop control mechanism (e.g.,
> Parser+DoWhileStatementNode in System.Management.Automation.dll) is running
> the loop. You can see it by opening System.Management.Automation.dll (in
> your Framework\v2.0.50727 folder on XP) in Reflector
> (http://www.aisto.com/roeder/dotnet/) and taking a look at
> Parser+FlowControlNode.Execute(). Hope this helps.
>
> -- Ryan Milligan
>


Certainly makes a good deal of sense, well found!

This reflector tool looks extremely useful, this will get a lot of
usage from me - kind of like having the MFC code to browse through.

I see that you can search for 'continue' and it finds
ContinueException in system.management.automation, but how did you
then find a reference to that tucked away in the FlowControl.Execute
method? I can't see a way to search all of the disassembled code?

Do you think there's a way that you could debug into the code that
reflector shows? Maybe by inserting a 'stop' command in a .ps1 file
(or whatever the powershell equivalent of an _asm int 3; breakpoint
call is) and then hooking it up to an instance of VS2005 for a debug
session?

Many thanks,

Duncan

My System SpecsSystem Spec
Old 04-06-2007   #6 (permalink)
Ryan Milligan


 
 

Re: FYI: 'continue' in 'for' loops is VERY slow

Check out the "Analyzer" feature -- right click on something in the left
pane and select Analyzer (or select it and press ctrl-R), and a tree view
will open up under the code view. Expand that, and you'll see nodes like
"Depends Upon", "Used By", etc, depending on what kind of node you selected.
If you selected ContinueException, you can expand the Used By node and see
the list of methods that use the type. Select one and press space, and
you'll see it in the code view. Pretty nifty, eh?

As for debugging the code generated by Reflector, I've thought about this
myself many times. Basically, you'd need to write an extension to Reflector
that would generate a folder of source code, and a .pdb file from the .dll
that maps offsets in the IL to lines in the generated source code. I haven't
looked to see if the Reflector API provides access to all the information
you would need, but I suspect that it might. Maybe I'll get around to
looking into it some time.

-- Ryan Milligan

"Duncan Smith" <DSmith1974@googlemail.com> wrote in message
news:1175849380.925327.283700@w1g2000hsg.googlegroups.com...
> On Apr 4, 10:28 pm, "Ryan Milligan" <Cei...@hotmail.com> wrote:
>> If I had to guess, I'd say it's because continue, break and return are
>> all
>> implemented by throwing exceptions which are caught and handled by the
>> Execute() method of whichever loop control mechanism (e.g.,
>> Parser+DoWhileStatementNode in System.Management.Automation.dll) is
>> running
>> the loop. You can see it by opening System.Management.Automation.dll (in
>> your Framework\v2.0.50727 folder on XP) in Reflector
>> (http://www.aisto.com/roeder/dotnet/) and taking a look at
>> Parser+FlowControlNode.Execute(). Hope this helps.
>>
>> -- Ryan Milligan
>>

>
> Certainly makes a good deal of sense, well found!
>
> This reflector tool looks extremely useful, this will get a lot of
> usage from me - kind of like having the MFC code to browse through.
>
> I see that you can search for 'continue' and it finds
> ContinueException in system.management.automation, but how did you
> then find a reference to that tucked away in the FlowControl.Execute
> method? I can't see a way to search all of the disassembled code?
>
> Do you think there's a way that you could debug into the code that
> reflector shows? Maybe by inserting a 'stop' command in a .ps1 file
> (or whatever the powershell equivalent of an _asm int 3; breakpoint
> call is) and then hooking it up to an instance of VS2005 for a debug
> session?
>
> Many thanks,
>
> Duncan
>



My System SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
Is there a 'continue' construct for loops in VBScript VB Script
Loops inside Cmdlets PowerShell
Task manager loops back? Vista General
Traps and Foreach loops PowerShell
Next fucntion in loops? PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46