0

I'm attempting to add performance to a script that has an array of data of over 10,000 entries, then use it in a foreach-object statement to fill a blank ArrayList with new data by calling another function. I've been reading how I shouldn't use +=, which is how I learned, because the performance is dreadful as it tears down the array and rebuilds it for each item. The issue I have is I need to call a function to fill an empty ArrayList, but I don't seem to be able to do this inside the .Add() method.

Old code:

Function get_gfe
Function get_os

$gfe   =  [System.Collections.ArrayList]@()
$gfe   = get_gfe
$getos = [System.Collections.ArrayList]@()

$gfe | foreach { $getos     += get_os $_} 

This takes over an hour to fill $getos with the data. I was hoping to use something like this instead, but it doesn't work, any help would be appreciated

$gfe | foreach { [void]$getos.Add(get_os $_)} 

I know that you can use .Add($_), but that doesn't meet my needs and I couldn't find any references to using other code or calling functions inside the .Add()method.

Thanks in advance!

1
  • .Add(get_os $_) -> .Add((get_os $_)) Commented Dec 17, 2019 at 19:26

3 Answers 3

3

Why not expand the foreach-loop to something like this:

foreach ($entry in $gfe){
    $os = get_os $entry
    [void]$getos.add($os)
}

A foreach-loop also saves time compared to | piping into foreach-object.

Although of course since I don't know what your functions are actually doing, this could not be the most effective way to save time. You can determine that with measure-command.

Sign up to request clarification or add additional context in comments.

Comments

0

Is it absolutely vital that $getos is of type System.Collections.ArrayList instead of a 'normal' array (System.Object[]) ?

If not, I think the next code could perform faster:

$getos = foreach ($entry in $gfe) {
    get_os $entry  # output the result of function get_os and collect in variable $getos
}

4 Comments

It's not vital at all, typically I would just have created the array as $getos = @(). I used to write the foreach statements like you have written, but I thought I had read that using the piping method was faster, which in my case, isn't.
Actually, the method you are proposing is different, I am trying it now, stay tuned.
@bdjenky I'm staying tuned.. Anything to report yet?
I have tried all the methods commented above, all using the Measure-Object command. All were in the 50 minute range to complete, which is near what I experienced using regular arrays. It might be that what I'm trying to accomplish is already "optimized". The function get_os, when ran manually with the proper Parameter, takes less than a second to show the data, so it must just be that PS is slow to go through the loop of all the serial numbers and feed them into that function. I'm at a loss.
0

Thanks to all for the recommendations, they've helped me to gain a better understanding of foreach, arrays, and arrayLists. We've suspect the slowness is related to the foreach loop accessing a function, which uses an API for each serial number. We had recently upgrade our MDM console and swapped out the underlying hardware.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.