diff --git a/internal/stack/record.go b/internal/stack/record.go index 138b20efa..158ec8223 100644 --- a/internal/stack/record.go +++ b/internal/stack/record.go @@ -62,7 +62,18 @@ func PackagePath(b bool) recordOption { } } -func Record(depth int, opts ...recordOption) string { +type call struct { + function uintptr + file string + line int +} + +func Call(depth int) (call call) { + call.function, call.file, call.line, _ = runtime.Caller(depth + 1) + return call +} + +func (call call) Record(opts ...recordOption) string { optionsHolder := recordOptions{ packagePath: true, packageName: true, @@ -75,13 +86,13 @@ func Record(depth int, opts ...recordOption) string { for _, opt := range opts { opt(&optionsHolder) } - function, file, line, _ := runtime.Caller(depth + 1) - name := runtime.FuncForPC(function).Name() + name := runtime.FuncForPC(call.function).Name() var ( pkgPath string pkgName string structName string funcName string + file = call.file ) if i := strings.LastIndex(file, "/"); i > -1 { file = file[i+1:] @@ -147,7 +158,7 @@ func Record(depth int, opts ...recordOption) string { buffer.WriteString(file) if optionsHolder.line { buffer.WriteByte(':') - fmt.Fprintf(buffer, "%d", line) + fmt.Fprintf(buffer, "%d", call.line) } if closeBrace { buffer.WriteByte(')') @@ -155,3 +166,11 @@ func Record(depth int, opts ...recordOption) string { } return buffer.String() } + +func (call call) FunctionID() string { + return call.Record(Lambda(false), FileName(false)) +} + +func Record(depth int, opts ...recordOption) string { + return Call(depth + 1).Record(opts...) +} diff --git a/internal/stack/record_test.go b/internal/stack/record_test.go index 7baee43b3..d0cdec245 100644 --- a/internal/stack/record_test.go +++ b/internal/stack/record_test.go @@ -256,3 +256,31 @@ func TestRecord(t *testing.T) { }) } } + +func BenchmarkCall(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Call(0) + } +} + +func BenchmarkRecord(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Record(0) + } +} + +func BenchmarkCallRecord(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Call(0).Record() + } +} + +func BenchmarkCallFuncionID(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = Call(0).FunctionID() + } +}