Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmark function for getSnippetHash #758

Merged
merged 6 commits into from
Sep 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/workflows/benchstat-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: benchstat

on: [pull_request]

jobs:
benchstat:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: '1.19'

# Generate benchmark report for main branch
- name: Checkout
uses: actions/checkout@v3
with:
ref: main
- name: Benchmark
run: go test ./... -count=10 -run="^$" -bench=. -benchmem | tee -a bench.txt
- name: Upload Benchmark
uses: actions/upload-artifact@v3
with:
name: bench-current
path: bench.txt

# Generate benchmark report for the PR
- name: Checkout
uses: actions/checkout@v3
- name: Benchmark
run: go test ./... -count=10 -run="^$" -bench=. -benchmem | tee -a bench.txt
- name: Upload Benchmark
uses: actions/upload-artifact@v3
with:
name: bench-incoming
path: bench.txt

# Compare the two reports
- name: Checkout
uses: actions/checkout@v3
- name: Install benchstat
run: go install golang.org/x/perf/cmd/benchstat@latest
- name: Download Incoming
uses: actions/download-artifact@v3
with:
name: bench-incoming
path: bench-incoming
- name: Download Current
uses: actions/download-artifact@v3
with:
name: bench-current
path: bench-current
- name: Benchstat Results
run: benchstat bench-current/bench.txt bench-incoming/bench.txt | tee -a benchstat.txt
- name: Upload benchstat results
uses: actions/upload-artifact@v3
with:
name: benchstat
path: benchstat.txt
- name: Read benchstat.txt
id: benchstat_content
uses: juliangruber/read-file-action@v1
with:
path: ./benchstat.txt
- name: Post PR Comment
uses: thollander/actions-comment-pull-request@v1
with:
message: |
Benchstat (compared to main):

```
${{ steps.benchstat_content.outputs.content }}
```
comment_includes: 'Benchstat (compared to main):'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83 changes: 83 additions & 0 deletions pkg/jsonnet/imports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package jsonnet

import (
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -23,3 +27,82 @@ func TestTransitiveImports(t *testing.T) {
"trees/peach.jsonnet",
}, imports)
}

const testFile = `
local localImport = <IMPORT>;
local myFunc = function() <IMPORT>;

{
local this = self,

attribute: {
name: 'test',
value: self.name,
otherValue: 'other ' + self.value,
},
nested: {
nested: {
nested: {
nested: {
nested1: {
nested: {
nested1: {
nested: {
attribute: <IMPORT>,
},
},
nested2: {
strValue: this.nested.nested.nested,
},
},
},
nested2: {
intValue: 1,
importValue: <IMPORT>,
},
},
},
},
},

other: myFunc(),
useLocal: localImport,
}`

func BenchmarkGetSnippetHash(b *testing.B) {
// Create a very large and complex project
tempDir := b.TempDir()

var mainContentSplit []string
for i := 0; i < 1000; i++ {
mainContentSplit = append(mainContentSplit, fmt.Sprintf("(import 'file%d.libsonnet')", i))
}
require.NoError(b, os.WriteFile(filepath.Join(tempDir, "main.jsonnet"), []byte(strings.Join(mainContentSplit, " + ")), 0644))
for i := 0; i < 1000; i++ {
err := os.WriteFile(
filepath.Join(tempDir, fmt.Sprintf("file%d.libsonnet", i)),
[]byte(strings.ReplaceAll(testFile, "<IMPORT>", fmt.Sprintf("import 'file%d.libsonnet'", i+1))),
0644,
)
require.NoError(b, err)
}
require.NoError(b, os.WriteFile(filepath.Join(tempDir, "file1000.libsonnet"), []byte(`"a string"`), 0644))
julienduchesne marked this conversation as resolved.
Show resolved Hide resolved

// Create a VM. It's important to reuse the same VM
// While there is a caching mechanism that normally shouldn't be shared in a benchmark iteration,
// it's useful to evaluate its impact here, because the caching will also improve the evaluation performance afterwards.
vm := MakeVM(Opts{ImportPaths: []string{tempDir}})
content, err := os.ReadFile(filepath.Join(tempDir, "main.jsonnet"))
require.NoError(b, err)

// Run the benchmark
julienduchesne marked this conversation as resolved.
Show resolved Hide resolved
mainPath := filepath.Join(tempDir, "main.jsonnet")
c := string(content)
b.ResetTimer()
for i := 0; i < b.N; i++ {
fileHashes = sync.Map{}
hash, err := getSnippetHash(vm, mainPath, c)
require.NoError(b, err)
require.Equal(b, "XrkW8N2EvkFMvdIuHTsGsQespVUl9_xiFmM7v1mqX5s=", hash)
}
}