PowerShell unfortunately makes it quite easy to write inefficient code. Many people, for example, use the += syntax to populate an array. That is not recommended.
| |
We can measure how long the execution of a scriptblock takes with Measure-Command. On my test VM, the execution of the code above took over 2 seconds.
Reason
The reason is that arrays in PowerShell are actually static. They cannot really be extended with new entries. Instead, the contents of the array are copied, the new entry is added, and the result is stored in a new array object. In most cases, the old array is then stored in the same variable as before, which makes this process not very visible and easy to overlook.
Alternatives
There are several alternatives to the += method.
Capture the pipeline
If the data in the array only needs to be created once and does not need to be modified, I prefer the following approach. I take the variable in which I want to store the array and simply assign the output of my loop to it. No assignment takes place inside the loop itself; instead, an object is output. Initializing the variable as an array, for example with $MeinArray = @(), is also unnecessary in this case.
| |
Generic List
If the data also needs to be changed, a generic list is practical. It must be initialized using a .NET method, which is slightly more complicated than normal PowerShell cmdlets. But the code can of course be copied, so it is not really a problem.
| |
I also show this in more detail in a video in the free PowerShell course.
Other alternatives
There are also other alternatives, such as hashtables.
| |
Improvements in PowerShell 7.5
From PowerShell 7.5 onward (expected to arrive in November 2024), the problem is somewhat mitigated. The += method works much faster there than in previous PowerShell versions. It is still not 100 percent ideal, however, because data still needs to be copied unnecessarily through memory.
Measure performance
With the following code, I measured the speed of += vs. generic lists. The test code for “Allocated Memory” only works in PowerShell 7, not in Windows PowerShell 5.1.
| |

