tlog.app/go/loc@v0.6.2-0.20231112073106-b6382a0ac518/README.md (about) 1 [![Documentation](https://pkg.go.dev/badge/tlog.app/go/loc)](https://pkg.go.dev/tlog.app/go/loc?tab=doc) 2 [![Go workflow](https://github.com/tlog-dev/loc/actions/workflows/go.yml/badge.svg)](https://github.com/tlog-dev/loc/actions/workflows/go.yml) 3 [![CircleCI](https://circleci.com/gh/tlog-dev/loc.svg?style=svg)](https://circleci.com/gh/tlog-dev/loc) 4 [![codecov](https://codecov.io/gh/tlog-dev/loc/tags/latest/graph/badge.svg)](https://codecov.io/gh/tlog-dev/loc) 5 [![Go Report Card](https://goreportcard.com/badge/tlog.app/go/loc)](https://goreportcard.com/report/tlog.app/go/loc) 6 ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/tlog-dev/loc?sort=semver) 7 8 # loc 9 10 It's a fast, alloc-free and convinient version of `runtime.Caller`. 11 12 Performance benefits are available when using the `nikandfor_loc_unsafe` build tag. This relies on the internal runtime implementation, which means that older versions of the package may not compile with future versions of Go. Without the tag, it is safe to use with any version of Go. 13 14 It was born from [tlog](https://tlog.app/go/tlog). 15 16 ## What is similar 17 18 Caller 19 20 ```go 21 pc := loc.Caller(1) 22 ok := pc != 0 23 name, file, line := pc.NameFileLine() 24 e := pc.FuncEntry() 25 26 // is similar to 27 28 pc, file, line, ok := runtime.Caller(1) 29 f := runtime.FuncForPC(pc) 30 name := f.Name() 31 e := f.Entry() 32 ``` 33 34 Callers 35 36 ```go 37 pcs := loc.Callers(1, 3) 38 // or 39 var pcsbuf [3]loc.PC 40 pcs := loc.CallersFill(1, pcsbuf[:]) 41 42 for _, pc := range pcs { 43 name, file, file := pc.NameFileLine() 44 } 45 46 // is similar to 47 var pcbuf [3]uintptr 48 n := runtime.Callers(2, pcbuf[:]) 49 50 frames := runtime.CallersFrames(pcbuf[:n]) 51 for { 52 frame, more := frames.Next() 53 54 _, _, _ = frame.Function, frame.File, frame.Line 55 56 if !more { 57 break 58 } 59 } 60 ``` 61 62 ## What is different 63 64 ### Normalized path 65 66 `loc` returns cropped filepath. 67 ``` 68 github.com/nikandfor/loc/func_test.go 69 70 # vs 71 72 /home/nik/nikandfor/loc/github.com/nikandfor/loc/func_test.go 73 ``` 74 75 ### Performance 76 77 In `loc` the full cycle (get pc than name, file and line) takes 360=200+160 (200+0 when you repeat) ns whereas runtime takes 690 (640 without func name) + 2 allocs per each frame. 78 79 It's up to 3.5x improve. 80 81 ``` 82 BenchmarkLocationCaller-8 5844801 201.8 ns/op 0 B/op 0 allocs/op 83 BenchmarkLocationNameFileLine-8 7313388 156.5 ns/op 0 B/op 0 allocs/op 84 BenchmarkRuntimeCallerNameFileLine-8 1709940 689.1 ns/op 216 B/op 2 allocs/op 85 BenchmarkRuntimeCallerFileLine-8 1917613 642.1 ns/op 216 B/op 2 allocs/op 86 ```