Skip to content

Commit dd2c292

Browse files
authored
ResourceBase: Performance optimizations (#47)
1 parent d7c5fbe commit dd2c292

File tree

8 files changed

+63
-35
lines changed

8 files changed

+63
-35
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- `ResourceBase`
1414
- Cache properties not in desired state.
1515
- Make `Set()` call `Test()` and `Test()` call `Get()`.
16+
- Remove use of array addition and `ForEach-Object`.
1617

1718
### Removed
1819

RequiredModules.psd1

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
}
99

1010
# Build dependencies needed for using the module
11-
'DscResource.Common' = 'latest'
11+
'DscResource.Common' = @{
12+
Version = 'latest'
13+
Parameters = @{
14+
AllowPrerelease = $true
15+
}
16+
}
1217

1318
# Build dependencies for the pipeline
1419
InvokeBuild = 'latest'
@@ -20,7 +25,12 @@
2025
Sampler = 'latest'
2126
'Sampler.GitHubTasks' = 'latest'
2227
MarkdownLinkCheck = 'latest'
23-
'DscResource.Test' = 'latest'
28+
'DscResource.Test' = @{
29+
Version = 'latest'
30+
Parameters = @{
31+
AllowPrerelease = $true
32+
}
33+
}
2434

2535
'DscResource.DocGenerator' = 'latest'
2636
PlatyPS = 'latest'

source/Classes/010.ResourceBase.ps1

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,12 @@ class ResourceBase
7878

7979
$dscResourceObject = [System.Activator]::CreateInstance($this.GetType())
8080

81+
$currentStateResultKeys = @($getCurrentStateResult.Keys)
82+
8183
# Set values returned from the derived class' GetCurrentState().
8284
foreach ($propertyName in $this.PSObject.Properties.Name)
8385
{
84-
if ($propertyName -in @($getCurrentStateResult.Keys) -and $null -ne $getCurrentStateResult.$propertyName)
86+
if ($propertyName -in $currentStateResultKeys -and $null -ne $getCurrentStateResult.$propertyName)
8587
{
8688
$dscResourceObject.$propertyName = $getCurrentStateResult.$propertyName
8789
}
@@ -92,7 +94,7 @@ class ResourceBase
9294
# Set key property values unless it was returned from the derived class' GetCurrentState().
9395
foreach ($propertyName in $this.CachedKeyProperties.Keys)
9496
{
95-
if ($propertyName -notin @($getCurrentStateResult.Keys))
97+
if ($propertyName -notin $currentStateResultKeys)
9698
{
9799
# Add the key value to the instance to be returned.
98100
$dscResourceObject.$propertyName = $this.$propertyName
@@ -157,10 +159,10 @@ class ResourceBase
157159
# The Get() method is called by Test().
158160
$propertiesToModify = $this.PropertiesNotInDesiredState | ConvertFrom-CompareResult
159161

160-
$propertiesToModify.Keys |
161-
ForEach-Object -Process {
162-
Write-Verbose -Message ($this.localizedData.SetProperty -f $_, $propertiesToModify.$_)
163-
}
162+
foreach ($property in $propertiesToModify.Keys)
163+
{
164+
Write-Verbose -Message ($this.localizedData.SetProperty -f $property, $propertiesToModify.$property)
165+
}
164166

165167
<#
166168
Call the Modify() method with the properties that should be enforced
@@ -202,7 +204,7 @@ class ResourceBase
202204
CurrentValues = $currentState
203205
DesiredValues = $this.CachedDesiredState
204206
Properties = $this.CachedDesiredState.Keys
205-
ExcludeProperties = ($excludeProperties + $this.ExcludeDscProperties) | Select-Object -Unique
207+
ExcludeProperties = @(($excludeProperties + $this.ExcludeDscProperties) | Sort-Object -Unique)
206208
IncludeValue = $true
207209
# This is needed to sort complex types.
208210
SortArrayValues = $true

source/Private/ConvertFrom-CompareResult.ps1

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ function ConvertFrom-CompareResult
3535

3636
process
3737
{
38-
$CompareResult | ForEach-Object -Process {
39-
$returnHashtable[$_.Property] = $_.ExpectedValue
38+
foreach ($r in $CompareResult)
39+
{
40+
$returnHashtable[$r.Property] = $r.ExpectedValue
4041
}
4142
}
4243

source/Private/ConvertFrom-Reason.ps1

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,24 @@ function ConvertFrom-Reason
3737
begin
3838
{
3939
# Always return an empty array if there are nothing to convert.
40-
$reasonsAsHashtable = [System.Collections.Hashtable[]] @()
40+
$reasonsAsHashtable = [System.Collections.Generic.List[System.Collections.Hashtable]]::new()
4141
}
4242

4343
process
4444
{
4545
foreach ($currentReason in $Reason)
4646
{
47-
$reasonsAsHashtable += [System.Collections.Hashtable] @{
48-
Code = $currentReason.Code
49-
Phrase = $currentReason.Phrase
50-
}
47+
$reasonsAsHashtable.Add(
48+
[System.Collections.Hashtable] @{
49+
Code = $currentReason.Code
50+
Phrase = $currentReason.Phrase
51+
}
52+
)
5153
}
5254
}
5355

5456
end
5557
{
56-
return , [System.Collections.Hashtable[]] $reasonsAsHashtable
58+
return , [System.Collections.Hashtable[]] $reasonsAsHashtable.ToArray()
5759
}
5860
}

source/Private/Get-ClassName.ps1

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,22 @@ function Get-ClassName
4343
begin
4444
{
4545
# Create a list of the inherited class names
46-
$class = @()
46+
$class = [System.Collections.Generic.List[System.String]]::new()
4747
}
4848

4949
process
5050
{
51-
$class += $InputObject.GetType().FullName
51+
$inputObjectType = $InputObject.GetType()
52+
53+
$class.Add($inputObjectType.FullName)
5254

5355
if ($Recurse.IsPresent)
5456
{
55-
$parentClass = $InputObject.GetType().BaseType
57+
$parentClass = $inputObjectType.BaseType
5658

5759
while ($parentClass -ne [System.Object])
5860
{
59-
$class += $parentClass.FullName
61+
$class.Add($parentClass.FullName)
6062

6163
$parentClass = $parentClass.BaseType
6264
}
@@ -65,6 +67,6 @@ function Get-ClassName
6567

6668
end
6769
{
68-
return , [System.String[]] $class
70+
return , [System.String[]] $class.ToArray()
6971
}
7072
}

source/Private/Resolve-Reason.ps1

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<#
22
.SYNOPSIS
3-
Returns a array of the type `[Reason]`.
3+
Returns an array of the type `[Reason]`.
44
55
.DESCRIPTION
66
This command builds an array from the properties that is returned by the command
@@ -43,7 +43,7 @@ function Resolve-Reason
4343
begin
4444
{
4545
# Always return an empty array if there are no properties to add.
46-
$reasons = [Reason[]] @()
46+
$reasons = [System.Collections.Generic.List[Reason]]::new()
4747
}
4848

4949
process
@@ -60,7 +60,7 @@ function Resolve-Reason
6060
$propertyExpectedValue = $currentProperty.ExpectedValue
6161
}
6262

63-
if ($property.ActualValue -is [System.Enum])
63+
if ($currentProperty.ActualValue -is [System.Enum])
6464
{
6565
# Return the string representation of the value so that conversion to json is correct.
6666
$propertyActualValue = $currentProperty.ActualValue.ToString()
@@ -99,20 +99,22 @@ function Resolve-Reason
9999
$propertyExpectedValueJson = $propertyExpectedValueJson -replace '\\\\', '\'
100100
}
101101

102-
$reasons += [Reason] @{
103-
Code = '{0}:{0}:{1}' -f $ResourceName, $currentProperty.Property
104-
# Convert the object to JSON to handle complex types.
105-
Phrase = 'The property {0} should be {1}, but was {2}' -f @(
106-
$currentProperty.Property,
107-
$propertyExpectedValueJson,
108-
$propertyActualValueJson
109-
)
110-
}
102+
$reasons.Add(
103+
[Reason] @{
104+
Code = ('{0}:{0}:{1}' -f $ResourceName, $currentProperty.Property)
105+
# Convert the object to JSON to handle complex types.
106+
Phrase = ('The property {0} should be {1}, but was {2}' -f
107+
$currentProperty.Property,
108+
$propertyExpectedValueJson,
109+
$propertyActualValueJson
110+
)
111+
}
112+
)
111113
}
112114
}
113115

114116
end
115117
{
116-
return $reasons
118+
return [Reason[]] $reasons.ToArray()
117119
}
118120
}

tests/Unit/Classes/ResourceBase.Tests.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,14 @@ $script:mockResourceBaseInstance = [MyMockResource]::new()
12441244
Add-Member -MemberType ScriptMethod -Name 'Modify' -Value {
12451245
$script:modifyMethodCallCount++
12461246
} -Force
1247+
1248+
$mockResourceBaseInstance.PropertiesNotInDesiredState = @(
1249+
@{
1250+
Property = 'MyResourceProperty2'
1251+
ExpectedValue = 'MyNewValue1'
1252+
ActualValue = 'MyValue1'
1253+
}
1254+
)
12471255
}
12481256

12491257
Mock -CommandName ConvertFrom-CompareResult -MockWith {

0 commit comments

Comments
 (0)