Skip to content

Commit

Permalink
add benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
KnicKnic committed Oct 21, 2019
1 parent a31150f commit 8bff00c
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
1 change: 1 addition & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ steps:
copy native-powershell\host.h .\pkg\powershell\ ;
copy native-powershell\x64\Release\psh_host.dll . ;
copy native-powershell\x64\Release\psh_host.dll .\pkg\powershell\ ;
copy native-powershell\x64\Release\psh_host.dll .\tests\benchmarks\ ;
mkdir c:\go_tmp;
$env:GOPATH="c:\go_tmp";
$env:GOBIN=$env:GOPATH + "\bin";
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module github.com/KnicKnic/go-powershell

go 1.12

require golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
require (
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb
k8s.io/klog v1.0.0
)
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
105 changes: 105 additions & 0 deletions tests/benchmarks/benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package benchmarks

// this file is used to help benchmark the impact of recreating the runspace every time, or if we should cache them.
// go test . -count 1 -v -run .*Power.*

import (
"testing"

"sync"

"github.com/KnicKnic/go-powershell/pkg/powershell"
)

func executePowershellFullCreate(script string, namedArgs map[string]interface{}) (obj []string, err error) {

runspace := powershell.CreateRunspaceSimple()
defer runspace.Close()
return executePowershellCommon(runspace, script, namedArgs)
}

func executePowershellBuffered(script string, namedArgs map[string]interface{}) (obj []string, err error) {
runspace := <-runspaceInstances
defer func() { runspaceInstances <- runspace }()

return executePowershellCommon(runspace, script, namedArgs)
}

func executePowershellCommon(runspace powershell.Runspace, script string, namedArgs map[string]interface{}) (obj []string, err error) {

results := runspace.ExecScript(script, true, namedArgs)
defer results.Close()

if !results.Success() {
exception := results.Exception.ToString()
panic(exception)
//return []string{}, errors.New(exception)
}

strResults := make([]string, len(results.Objects), len(results.Objects))
for i, result := range results.Objects {
strResults[i] = result.ToString()
}

return strResults, nil
}

// after running a few tests, I do not believe that buffering powershell sessions is worth the complexity of the code.
// with a 10 unit worker pool, running 100 powershell tests took .65 seconds
// sequentially running 100 tests and creating and destroying the runspace every time it took 3.26 seconds

var runspaceInstances chan powershell.Runspace

func init() {
runspaceInstanceCount := 10
runspaceInstances = make(chan powershell.Runspace, runspaceInstanceCount)
for i := 0; i < runspaceInstanceCount; i++ {
runspaceInstances <- powershell.CreateRunspaceSimple()
}
}

var powershellTestRunSize int = 100

var powershellCommand = "start-sleep -milliseconds 100"

// var powershellCommand = "$a = 1+1"

func Test_LotsPowershellParallelBuffered(t *testing.T) {

var wg sync.WaitGroup
simplePowershellCommand := func(wg *sync.WaitGroup) { executePowershellBuffered(powershellCommand, nil); wg.Done() }

for i := 0; i < powershellTestRunSize; i++ {
wg.Add(1)
go simplePowershellCommand(&wg)
}
wg.Wait()

}
func Test_LotsPowershellParallel(t *testing.T) {

var wg sync.WaitGroup
simplePowershellCommand := func(wg *sync.WaitGroup) { executePowershellFullCreate(powershellCommand, nil); wg.Done() }

for i := 0; i < powershellTestRunSize; i++ {
wg.Add(1)
go simplePowershellCommand(&wg)
}
wg.Wait()

}

func Test_LotsPowershellSequentialBuffered(t *testing.T) {

for i := 0; i < powershellTestRunSize; i++ {
executePowershellBuffered(powershellCommand, nil)
}

}

func Test_LotsPowershellSequential(t *testing.T) {

for i := 0; i < powershellTestRunSize; i++ {
executePowershellFullCreate(powershellCommand, nil)
}
}

0 comments on commit 8bff00c

Please sign in to comment.