Skip to content

Commit

Permalink
Benchmark improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
MacroPower committed Dec 31, 2024
1 parent e72bc70 commit aa569be
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 59 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@ import kcl_plugin.os

> See the extension docs for [OS](./docs/os_extensions.md), [HTTP](./docs/http_extensions.md), and [Helm](./docs/helm_extensions.md).
**Quickly render resources at runtime**, if you want to. KCL itself is incredibly fast, and by utilizing the Helm source implementation from Argo CD, macropower/kclx benches ~2x faster than the Helm Go SDK. Additionally, the same caching patterns are followed, meaning that normal Helm caching is handled with namespace and, [eventually](https://github.com/MacroPower/kclx/issues/2), project awareness.

> See [Benchmarks](./benchmarks/).
## Installation

Binaries are posted in [releases](https://github.com/MacroPower/kclx/releases). Images and OCI artifacts are available under [packages](https://github.com/MacroPower/kclx/pkgs/container/kclx).
Expand Down
16 changes: 14 additions & 2 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,23 @@ tasks:
go test -vet=all -tags={{.BUILD_TAGS}} ./...
go-bench:
desc: Benchmarks Go code
desc: Run Go benchmarks
summary: |
Run Go benchmarks
Args:
PKG: Go package to test (default: ./...)
FLAGS: Additional flags to pass to `go test` (default: "")
Examples:
task go-bench PKG=./pkg/helm FLAGS="-cpuprofile profile.out -run=^\$"
vars:
PKG: '{{.PKG | default "./..."}}'
FLAGS: '{{.FLAGS | default ""}}'
cmds:
- |
export CC=$CC_{{.C_ENV}} CXX=$CXX_{{.C_ENV}}
go test -bench=. -benchmem -tags={{.BUILD_TAGS}} ./...
go test -bench=. -benchmem -tags={{.BUILD_TAGS}} {{.FLAGS}} {{.PKG}}
go-build:
desc: Builds Go binaries
Expand Down
3 changes: 2 additions & 1 deletion devbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"nodePackages.prettier": "3.3",
"kubernetes-helm": "3.16.3",
"hyperfine": "1.19",
"cobra-cli": "1.3.0"
"cobra-cli": "1.3.0",
"graphviz": "12.2"
},
"env": {
"CGO_ENABLED": "1"
Expand Down
48 changes: 48 additions & 0 deletions devbox.lock
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,54 @@
}
}
},
"[email protected]": {
"last_modified": "2024-12-23T21:10:33Z",
"resolved": "github:NixOS/nixpkgs/de1864217bfa9b5845f465e771e0ecb48b30e02d#graphviz",
"source": "devbox-search",
"version": "12.2.0",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/2pad8nxbjvaljnf6n2p6a2w1462zav7x-graphviz-12.2.0",
"default": true
}
],
"store_path": "/nix/store/2pad8nxbjvaljnf6n2p6a2w1462zav7x-graphviz-12.2.0"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/dayd450xkldbpy2vl9r315dwj0473m4x-graphviz-12.2.0",
"default": true
}
],
"store_path": "/nix/store/dayd450xkldbpy2vl9r315dwj0473m4x-graphviz-12.2.0"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/hj9j4xl0qn1drhqa5hx2j372rl4q05hg-graphviz-12.2.0",
"default": true
}
],
"store_path": "/nix/store/hj9j4xl0qn1drhqa5hx2j372rl4q05hg-graphviz-12.2.0"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/aj4psc4x5p4f7gh7calsgxkr7y7gbgwd-graphviz-12.2.0",
"default": true
}
],
"store_path": "/nix/store/aj4psc4x5p4f7gh7calsgxkr7y7gbgwd-graphviz-12.2.0"
}
}
},
"[email protected]": {
"last_modified": "2024-12-03T12:40:06Z",
"resolved": "github:NixOS/nixpkgs/566e53c2ad750c84f6d31f9ccb9d00f823165550#hyperfine",
Expand Down
17 changes: 5 additions & 12 deletions pkg/helm/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"os"
"path/filepath"
"sync"
)

type PathEncoder interface {
Expand All @@ -22,7 +21,6 @@ type PathEncoder interface {
type TempPaths struct {
root string
pe PathEncoder
lock sync.RWMutex
}

func NewTempPaths(root string, pe PathEncoder) *TempPaths {
Expand All @@ -32,7 +30,7 @@ func NewTempPaths(root string, pe PathEncoder) *TempPaths {
panic(err)
}
return &TempPaths{
root: filepath.Join(root, "charts"),
root: chartPaths,
pe: pe,
}
}
Expand All @@ -59,20 +57,15 @@ func (p *TempPaths) GetPath(key string) (string, error) {

// GetPathIfExists gets a path for the given key if it exists. Otherwise, returns an empty string.
func (p *TempPaths) GetPathIfExists(key string) string {
p.lock.RLock()
defer p.lock.RUnlock()

if _, err := os.Stat(p.keyToPath(key)); err == nil {
return p.keyToPath(key)
path := p.keyToPath(key)
if _, err := os.Stat(path); err != nil {
return ""
}
return ""
return path
}

// GetPaths gets a copy of the map of paths.
func (p *TempPaths) GetPaths() map[string]string {
p.lock.RLock()
defer p.lock.RUnlock()

ds, err := os.ReadDir(p.root)
if err != nil {
panic(err)
Expand Down
33 changes: 22 additions & 11 deletions pkg/helm/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"path/filepath"

argohelm "github.com/argoproj/argo-cd/v2/util/helm"
ioutil "github.com/argoproj/argo-cd/v2/util/io"
pathutil "github.com/argoproj/argo-cd/v2/util/io/path"
"github.com/google/uuid"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -58,12 +57,28 @@ func NewChart(client ChartClient, opts TemplateOpts) *Chart {
// split into individual Kubernetes objects and returned as a slice of
// [unstructured.Unstructured] objects.
func (c *Chart) Template() ([]*unstructured.Unstructured, error) {
out, err := c.template()
if err != nil {
return nil, err
}

objs, err := SplitYAML(out)
if err != nil {
return nil, fmt.Errorf("error parsing helm template output: %w", err)
}

return objs, nil
}

func (c *Chart) template() ([]byte, error) {
chartPath, closer, err := c.Client.PullWithCreds(c.TemplateOpts.ChartName, c.TemplateOpts.RepoURL,
c.TemplateOpts.TargetRevision, c.TemplateOpts.Credentials, c.TemplateOpts.PassCredentials)
if err != nil {
return nil, fmt.Errorf("error pulling helm chart: %w", err)
}
defer ioutil.Close(closer)
defer func() {
_ = closer.Close()
}()

// isLocal controls helm temp dirs, does not seem to impact pull/template behavior.
isLocal := false
Expand All @@ -80,7 +95,7 @@ func (c *Chart) Template() ([]*unstructured.Unstructured, error) {
return nil, err
}
defer func() {
_ = os.RemoveAll(p)
_ = os.Remove(p)
}()

argoTemplateOpts := &argohelm.TemplateOpts{
Expand All @@ -102,13 +117,7 @@ func (c *Chart) Template() ([]*unstructured.Unstructured, error) {
return nil, fmt.Errorf("error templating helm chart: %w", err)
}
}

objs, err := SplitYAML([]byte(out))
if err != nil {
return nil, fmt.Errorf("error parsing helm template output: %w", err)
}

return objs, nil
return []byte(out), nil
}

// GetValuesJSONSchema pulls a Helm chart using the provided [TemplateOpts], and
Expand All @@ -121,7 +130,9 @@ func (c *Chart) GetValuesJSONSchema(gen JSONSchemaGenerator, match func(string)
if err != nil {
return nil, fmt.Errorf("error pulling helm chart: %w", err)
}
defer ioutil.Close(closer)
defer func() {
_ = closer.Close()
}()

unmatchedFiles := []string{}
matchedFiles := []string{}
Expand Down
23 changes: 23 additions & 0 deletions pkg/helm/chart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"path/filepath"
"testing"

argocli "github.com/argoproj/argo-cd/v2/util/cli"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"

Expand All @@ -13,6 +14,10 @@ import (
"github.com/MacroPower/kclx/pkg/jsonschema"
)

func init() {
argocli.SetLogLevel("warn")
}

func TestHelmChart(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -95,3 +100,21 @@ func TestHelmChart(t *testing.T) {
})
}
}

func BenchmarkHelmChart(b *testing.B) {
c := helm.NewChart(helmtest.DefaultTestClient, helm.TemplateOpts{
ChartName: "podinfo",
TargetRevision: "6.7.1",
RepoURL: "https://stefanprodan.github.io/podinfo",
})
_, err := c.Template()
require.NoError(b, err)

b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := c.Template()
require.NoError(b, err)
}
})
}
29 changes: 0 additions & 29 deletions pkg/plugin/helm/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,3 @@ func TestPluginHelmTemplate(t *testing.T) {
})
}
}

func BenchmarkPluginHelmTemplate(b *testing.B) {
inputKCLFile := filepath.Join(testDataDir, "input/simple.k")
inputKCL, err := os.ReadFile(inputKCLFile)
require.NoError(b, err)

client := native.NewNativeServiceClient()
_, err = client.ExecProgram(&gpyrpc.ExecProgram_Args{
KFilenameList: []string{"main.k"},
KCodeList: []string{string(inputKCL)},
Args: []*gpyrpc.Argument{},
})
require.NoError(b, err)

b.ResetTimer()

b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
client := native.NewNativeServiceClient()
result, err := client.ExecProgram(&gpyrpc.ExecProgram_Args{
KFilenameList: []string{"main.k"},
KCodeList: []string{string(inputKCL)},
Args: []*gpyrpc.Argument{},
})
require.NoError(b, err)
require.Empty(b, result.GetErrMessage())
}
})
}

0 comments on commit aa569be

Please sign in to comment.