It's fairly well documented that foreach processing speed varies depending on the way a foreach loop is carried out (ordered from fastest to slowest):
.ForEach()method- foreach ($item in $collection) {}
- $collection | ForEach-Object {}
- When working with (very) large collections, speed comparisons between #1 and #2 can be significant, and the overhead of piping makes #3 a non-candidate in those cases.
- #2 offers the
continuestatement, while #1 does not- Please correct/comment if this is inaccurate
- From what I've seen online and in real life,
returnis how to "continue" when using the.ForEach()method.
My questions:
- When the speed advantage of the
.ForEach()method is too big to settle forforeachand you need tocontinue, what is the proper way tocontinuewhen using.ForEach({})? - What are the implications or gotcha's you should be aware of when using
returninside the.ForEach()method?
Incorrect, the pipeline is very efficient, it's almost pair with
foreach(fastest way in PowerShell to enumerate a collection).ForEach-Objectis the inefficient one because it dot sources the scriptblock..ForEachis almost never a good a alternative, tests below clearly show that. In addition the output type is always aCollection<T>:.ForEachdoesn't stream output, meaning that there is no way to exit early from the loop withSelect-Object -First, this also means higher memory consumption.As for the 2nd question,
returnis the closest you can get tocontinueexiting early from the invocation, there are no gotchas there as long it is understood that it exits early from the current invocation and goes to the next item in the collection, however there is no real way tobreakthe loop using.ForEach.I believe it's already understood but,
breakandcontinueshould not be used outside of outside of a loop,switch, ortrap:If you're looking for performance you should rely on
foreachor a scriptblock with aprocessblock or function with aprocessblock.