github.com/nikandfor/loc@v0.5.1/README.md (about) 1 [![Documentation](https://pkg.go.dev/badge/github.com/nikandfor/loc)](https://pkg.go.dev/github.com/nikandfor/loc?tab=doc) 2 [![Go workflow](https://github.com/nikandfor/json/actions/workflows/go.yml/badge.svg)](https://github.com/nikandfor/json/actions/workflows/go.yml) 3 [![CircleCI](https://circleci.com/gh/nikandfor/loc.svg?style=svg)](https://circleci.com/gh/nikandfor/loc) 4 [![codecov](https://codecov.io/gh/nikandfor/loc/tags/latest/graph/badge.svg)](https://codecov.io/gh/nikandfor/loc) 5 [![GolangCI](https://golangci.com/badges/github.com/nikandfor/loc.svg)](https://golangci.com/r/github.com/nikandfor/loc) 6 [![Go Report Card](https://goreportcard.com/badge/github.com/nikandfor/loc)](https://goreportcard.com/report/github.com/nikandfor/loc) 7 ![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/nikandfor/loc?sort=semver) 8 9 # loc 10 11 It's a fast, alloc-free and convinient version of `runtime.Caller`. 12 13 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. 14 15 It was born from [tlog](https://github.com/tlog-dev/tlog). 16 17 ## What is similar 18 19 Caller 20 21 ```go 22 pc := loc.Caller(1) 23 ok := pc != 0 24 name, file, line := pc.NameFileLine() 25 e := pc.FuncEntry() 26 27 // is similar to 28 29 pc, file, line, ok := runtime.Caller(1) 30 f := runtime.FuncForPC(pc) 31 name := f.Name() 32 e := f.Entry() 33 ``` 34 35 Callers 36 37 ```go 38 pcs := loc.Callers(1, 3) 39 // or 40 var pcsbuf [3]loc.PC 41 pcs := loc.CallersFill(1, pcsbuf[:]) 42 43 for _, pc := range pcs { 44 name, file, file := pc.NameFileLine() 45 } 46 47 // is similar to 48 var pcbuf [3]uintptr 49 n := runtime.Callers(2, pcbuf[:]) 50 51 frames := runtime.CallersFrames(pcbuf[:n]) 52 for { 53 frame, more := frames.Next() 54 55 _, _, _ = frame.Function, frame.File, frame.Line 56 57 if !more { 58 break 59 } 60 } 61 ``` 62 63 ## What is different 64 65 ### Normalized path 66 67 `loc` returns cropped filepath. 68 ``` 69 github.com/nikandfor/loc/func_test.go 70 71 # vs 72 73 /home/nik/nikandfor/loc/github.com/nikandfor/loc/func_test.go 74 ``` 75 76 ### Performance 77 78 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. 79 80 It's up to 3.5x improve. 81 82 ``` 83 BenchmarkLocationCaller-8 5844801 201.8 ns/op 0 B/op 0 allocs/op 84 BenchmarkLocationNameFileLine-8 7313388 156.5 ns/op 0 B/op 0 allocs/op 85 BenchmarkRuntimeCallerNameFileLine-8 1709940 689.1 ns/op 216 B/op 2 allocs/op 86 BenchmarkRuntimeCallerFileLine-8 1917613 642.1 ns/op 216 B/op 2 allocs/op 87 ```