mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-28 14:07:14 +00:00
test/e2e/framework/log: optimize PrunedStack()
Use bytes instead of strings, and slice in-place filter (see https://github.com/golang/go/wiki/SliceTricks#filter-in-place) to avoid copying strings around. In my benchmark it shows almost 2x improvement: BenchmarkString-8 1477207 10198 ns/op BenchmarkBuffer-8 1561291 7622 ns/op BenchmarkInPlace-8 2295714 5202 ns/op String is the original implementation, Buffer is an intermediary one that uses strings.Builder, and InPlace is the one from this commit. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
parent
3ed0f1bec1
commit
78e98da1db
@ -17,10 +17,10 @@ limitations under the License.
|
|||||||
package framework
|
package framework
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo"
|
"github.com/onsi/ginkgo"
|
||||||
@ -78,12 +78,14 @@ var codeFilterRE = regexp.MustCompile(`/github.com/onsi/ginkgo/`)
|
|||||||
// This is a modified copy of PruneStack in https://github.com/onsi/ginkgo/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25:
|
// This is a modified copy of PruneStack in https://github.com/onsi/ginkgo/blob/f90f37d87fa6b1dd9625e2b1e83c23ffae3de228/internal/codelocation/code_location.go#L25:
|
||||||
// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter)
|
// - simplified API and thus renamed (calls debug.Stack() instead of taking a parameter)
|
||||||
// - source code filtering updated to be specific to Kubernetes
|
// - source code filtering updated to be specific to Kubernetes
|
||||||
func PrunedStack(skip int) string {
|
// - optimized to use bytes and in-place slice filtering from
|
||||||
fullStackTrace := string(debug.Stack())
|
// https://github.com/golang/go/wiki/SliceTricks#filter-in-place
|
||||||
stack := strings.Split(fullStackTrace, "\n")
|
func PrunedStack(skip int) []byte {
|
||||||
|
fullStackTrace := debug.Stack()
|
||||||
|
stack := bytes.Split(fullStackTrace, []byte("\n"))
|
||||||
// Ensure that the even entries are the method names and the
|
// Ensure that the even entries are the method names and the
|
||||||
// the odd entries the source code information.
|
// the odd entries the source code information.
|
||||||
if len(stack) > 0 && strings.HasPrefix(stack[0], "goroutine ") {
|
if len(stack) > 0 && bytes.HasPrefix(stack[0], []byte("goroutine ")) {
|
||||||
// Ignore "goroutine 29 [running]:" line.
|
// Ignore "goroutine 29 [running]:" line.
|
||||||
stack = stack[1:]
|
stack = stack[1:]
|
||||||
}
|
}
|
||||||
@ -94,13 +96,16 @@ func PrunedStack(skip int) string {
|
|||||||
if len(stack) > 2*skip {
|
if len(stack) > 2*skip {
|
||||||
stack = stack[2*skip:]
|
stack = stack[2*skip:]
|
||||||
}
|
}
|
||||||
prunedStack := []string{}
|
n := 0
|
||||||
for i := 0; i < len(stack)/2; i++ {
|
for i := 0; i < len(stack)/2; i++ {
|
||||||
// We filter out based on the source code file name.
|
// We filter out based on the source code file name.
|
||||||
if !codeFilterRE.Match([]byte(stack[i*2+1])) {
|
if !codeFilterRE.Match([]byte(stack[i*2+1])) {
|
||||||
prunedStack = append(prunedStack, stack[i*2])
|
stack[n] = stack[i*2]
|
||||||
prunedStack = append(prunedStack, stack[i*2+1])
|
stack[n+1] = stack[i*2+1]
|
||||||
|
n += 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(prunedStack, "\n")
|
stack = stack[:n]
|
||||||
|
|
||||||
|
return bytes.Join(stack, []byte("\n"))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user