PowerShell 배열 초기화
PowerShell에서 배열을 초기화하는 가장 좋은 방법은 무엇입니까?
예를 들어, 코드
$array = @()
for($i=0; $i -lt 5;$i++)
{
$array[$i] = $FALSE
}
오류를 생성
Array assignment failed because index '0' was out of range.
At H:\Software\PowerShell\TestArray.ps1:4 char:10
+ $array[$ <<<< i] = $FALSE
또 다른 대안 :
for ($i = 0; $i -lt 5; $i++)
{
$arr += @($false)
}
$ arr가 아직 정의되지 않은 경우 작동합니다.
참고 -이 작업을 수행하는 더 나은 (그리고 더 많은 성능) 방법이 있습니다 ... 아래의 https://stackoverflow.com/a/234060/4570을 예로 참조 하십시오 .
매우 간결한 두 가지 방법이 더 있습니다.
$arr1 = @(0) * 20
$arr2 = ,0 * 20
형식화 된 배열을 만들려면 생성자 의 기본값을 사용할 수도 있습니다 .
> $a = new-object bool[] 5
> $a
False
False
False
False
False
bool 의 기본값 은 분명히 false 이므로 귀하의 경우에 작동합니다. 마찬가지로 형식화 된 int [] 배열 을 생성 하면 기본값 인 0을 얻게됩니다.
배열을 초기화하는 데 사용하는 또 다른 멋진 방법은 다음과 같은 속기입니다.
> $a = ($false, $false, $false, $false, $false)
> $a
False
False
False
False
False
또는 범위를 초기화하고 싶을 때 유용하다고 생각되는 경우가 있습니다.
> $ a = (1..5) > $ a 1 2 삼 4 5
이것이 다소 도움이 되었기를 바랍니다!
원래 예제에서는 배열이 비어 있기 때문에 오류를 반환 한 다음 n 번째 요소에 액세스하여 값을 할당하려고합니다.
여기에 창의적인 답변이 많이 있으며,이 게시물을 읽기 전에는 몰랐던 많은 답변이 있습니다. 작은 어레이에는 모두 괜찮지 만 n0rd가 지적했듯이 성능에는 상당한 차이가 있습니다.
여기서는 Measure-Command를 사용하여 각 초기화에 걸리는 시간을 확인합니다. 짐작할 수 있듯이 명시 적 PowerShell 루프를 사용하는 모든 접근 방식은 .Net 생성자 또는 PowerShell 연산자 (IL 또는 네이티브 코드로 컴파일 됨)를 사용하는 접근 방식보다 느립니다.
요약
New-Object및@(somevalue)*n(100,000 요소에 대한 주위 20K 진드기가) 빠르다.- 범위 연산자를 사용하여 배열을 만드는
n..m것은 10 배 더 느립니다 (200k 틱). - 또는 (일명 , )를
Add()사용하여 이미 크기가 조정 된 배열을 반복하는 것처럼 메서드 와 함께 ArrayList를 사용하면 기준선 (2 천만 틱)보다 1000 배 느립니다 .for()ForEach-Objectforeach% - 추가하는
+=것은 최악입니다 (단지 1000 개 요소에 대해 2M 틱).
전반적으로 다음과 같은 이유로 array * n 이 "최고" 라고 말하고 싶습니다 .
- 빠르다.
- 유형의 기본값뿐만 아니라 모든 값을 사용할 수 있습니다.
- 반복되는 값을 만들 수 있습니다 (설명을 위해 powershell 프롬프트에 다음을 입력하십시오.
(1..10)*10 -join " "또는('one',2,3)*3). - 간결한 구문.
유일한 단점 :
- 분명하지 않습니다. 이전에이 구조를 본 적이 없다면 어떤 역할을하는지 분명하지 않습니다.
그러나 배열 요소를 어떤 값으로 초기화하려는 많은 경우에는 강력한 형식의 배열이 정확히 필요한 것입니다. 모든 것을으로 초기화하는 경우 $false배열은 $false또는 이외의 다른 항목을 보유 $true합니까? 그렇지 않은 경우 New-Object type[] n"최상의"접근 방식입니다.
테스팅
기본 배열을 만들고 크기를 지정한 다음 값을 할당합니다.
PS> Measure-Command -Expression {$a = new-object object[] 100000} | Format-List -Property "Ticks"
Ticks : 20039
PS> Measure-Command -Expression {for($i=0; $i -lt $a.Length;$i++) {$a[$i] = $false}} | Format-List -Property "Ticks"
Ticks : 28866028
Boolean 배열을 만드는 것은 Object 배열보다 약간 느립니다.
PS> Measure-Command -Expression {$a = New-Object bool[] 100000} | Format-List -Property "Ticks"
Ticks : 130968
이것이 무엇을하는지 명확하지 않습니다. New-Object에 대한 문서에서는 두 번째 매개 변수가 .Net 개체 생성자에 전달되는 인수 목록이라고 말합니다. 배열의 경우 매개 변수는 분명히 원하는 크기입니다.
+ =로 추가
PS> $a=@()
PS> Measure-Command -Expression { for ($i=0; $i -lt 100000; $i++) {$a+=$false} } | Format-List -Property "Ticks"
완료되기를 기다리는 데 지쳤으므로 ctrl + c 다음 :
PS> $a=@()
PS> Measure-Command -Expression { for ($i=0; $i -lt 100; $i++) {$a+=$false} } | Format-List -Property "Ticks"
Ticks : 147663
PS> $a=@()
PS> Measure-Command -Expression { for ($i=0; $i -lt 1000; $i++) {$a+=$false} } | Format-List -Property "Ticks"
Ticks : 2194398
(6 * 3)이 (6 + 6 + 6)과 개념적으로 유사 하듯이 ($ somearray * 3)은 ($ somearray + $ somearray + $ somearray)와 동일한 결과를 제공해야합니다. 그러나 배열에서 +는 덧셈이 아니라 연결입니다.
$ array + = $ element가 느린 경우 $ array * $ n도 느릴 것으로 예상 할 수 있지만 그렇지 않습니다.
PS> Measure-Command -Expression { $a = @($false) * 100000 } | Format-List -Property "Ticks"
Ticks : 20131
Java에 추가 할 때 여러 개체를 만들지 않도록 StringBuilder 클래스가있는 것처럼 PowerShell에는 ArrayList가있는 것 같습니다.
PS> $al = New-Object System.Collections.ArrayList
PS> Measure-Command -Expression { for($i=0; $i -lt 1000; $i++) {$al.Add($false)} } | Format-List -Property "Ticks"
Ticks : 447133
PS> $al = New-Object System.Collections.ArrayList
PS> Measure-Command -Expression { for($i=0; $i -lt 10000; $i++) {$al.Add($false)} } | Format-List -Property "Ticks"
Ticks : 2097498
PS> $al = New-Object System.Collections.ArrayList
PS> Measure-Command -Expression { for($i=0; $i -lt 100000; $i++) {$al.Add($false)} } | Format-List -Property "Ticks"
Ticks : 19866894
범위 연산자 및 Where-Object루프 :
PS> Measure-Command -Expression { $a = 1..100000 } | Format-List -Property "Ticks"
Ticks : 239863
Measure-Command -Expression { $a | % {$false} } | Format-List -Property "Ticks"
Ticks : 102298091
메모:
- 각 실행 (
$a=$null) 사이의 변수를 무효화했습니다 . - 테스트는 Atom 프로세서가있는 태블릿에서 이루어졌습니다. 다른 컴퓨터에서 더 빠른 속도를 볼 수 있습니다. [편집 : 데스크톱 컴퓨터에서 약 2 배 빠릅니다.]
- 여러 번 시도했을 때 약간의 변화가있었습니다. 정확한 숫자보다는 자릿수를 찾으십시오.
- Testing was with PowerShell 3.0 in Windows 8.
Acknowledgements
Thanks to @halr9000 for array*n, @Scott Saad and Lee Desmond for New-Object, and @EBGreen for ArrayList.
Thanks to @n0rd for getting me to think about performance.
$array = 1..5 | foreach { $false }
$array = @()
for($i=0; $i -lt 5; $i++)
{
$array += $i
}
Here's another idea. You have to remember, that it's .NET underneath:
$arr = [System.Array]::CreateInstance([System.Object], 5)
$arr.GetType()
$arr.Length
$arr = [Object[]]::new(5)
$arr.GetType()
$arr.Length
Result:
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
5
True True Object[] System.Array
5
Using new() has one distinct advantage: when you're programming in ISE and want to create an object, ISE will give you hint with all paramer combinations and their types. You don't have that with New-Object, where you have to remember the types and order of arguments.
The solution I found was to use the New-Object cmdlet to initialize an array of the proper size.
$array = new-object object[] 5
for($i=0; $i -lt $array.Length;$i++)
{
$array[$i] = $FALSE
}
If I don't know the size up front, I use an arraylist instead of an array.
$al = New-Object System.Collections.ArrayList
for($i=0; $i -lt 5; $i++)
{
$al.Add($i)
}
Or try this an idea. Works with powershell 5.0+.
[bool[]]$tf=((,$False)*5)
참고URL : https://stackoverflow.com/questions/226596/powershell-array-initialization
'Program Club' 카테고리의 다른 글
| Tomcat에 배포 된 Spring Boot War (0) | 2020.10.31 |
|---|---|
| Android에서 String.join의 대안? (0) | 2020.10.31 |
| Objective-c iPhone 백분율은 문자열을 인코딩합니까? (0) | 2020.10.30 |
| Vim에서 하나의 명령으로 많은 버퍼를 닫을 수 없습니다. (0) | 2020.10.30 |
| 쉼표를 구분 기호로 사용하여 여러 행을 하나로 변환 (0) | 2020.10.30 |
