I am trying to write a powershell script to generate about 9 million unique number. Is there any efficient way to do that?
$start = [long] $startNumber
$end = [long] $endNumber
$random = New-Object System.Random
$number = @()
while ($start -lt $end){
$customerObject = new-object PSObject
$randomnumber = $random.Next(100000000,999999999)
while ($number -contains $randomnumber) {
$randomnumber = $random.Next(100000000,999999999)
}
$number += $randomnumber
[long] $uniqueId = 2000000000 +[long] $randomnumber;
$customerObject | add-member -membertype NoteProperty -name CUSTOMERID -Value $uniqueId
$start++
$resultsarray += $customerObject
}
I would maintain a separate HashSet<int>
to keep track of the distinct values already generated.
A HashSet
doesn't preserve insertion order but is crazy-fast to perform lookups against, unlike a regular array in which lookup-performance will become quite sluggish after a while (which you've probably already seen yourself).
Secondly, avoid +=
at any cost. PowerShell arrays resize themselves by recreating and copying the underlying array to a slighter larger array. This constant resizing is going to hurt performance as well.
You can rely on the pipeline alone by simply "dropping" your variables on a line and assign the output from the entire while
loop to a variable that will then contain your random(ly ordered) sequence:
$random = New-Object System.Random
$set = New-Object 'System.Collections.Generic.HashSet[int]'
$limit = $endNumber - $startNumber
$sequence = while($set.Count -lt $limit)
{
# Generate random number
$n = $random.Next(100000000,999999999)
# Re-generate until a distinct value is produced
while($set.Contains($n)){
$n = $random.Next(100000000,999999999)
}
# Add value to set
[void]$set.Add($n)
# Let value "bubble up" to the variable
$n
}