Last active
March 3, 2019 21:58
-
-
Save jcchavezs/9064b9168cb2b02590c57f677ab5dd4c to your computer and use it in GitHub Desktop.
Benchmark B3 Single header parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package b3 | |
| import ( | |
| "testing" | |
| "github.com/openzipkin/zipkin-go" | |
| ) | |
| func BenchmarkParseSingleHeader(b *testing.B) { | |
| // run the Fib function b.N times | |
| cases := []struct { | |
| name string | |
| header string | |
| }{ | |
| {"sampling", "d"}, | |
| {"traceID_spanID", "000000000000007b00000000000001c8-000000000000007b"}, | |
| {"traceID_spanID_sampling", "000000000000007b00000000000001c8-000000000000007b-1"}, | |
| {"traceID_spanID_sampling_parentID", "000000000000007b00000000000001c8-000000000000007b-1-00000000000001c"}, | |
| } | |
| b.ResetTimer() | |
| for _, c := range cases { | |
| b.Run(c.name, func(b *testing.B) { | |
| for n := 0; n < b.N; n++ { | |
| ParseSingleHeader(c.header) | |
| } | |
| }) | |
| } | |
| } | |
| func BenchmarkParseSingleHeaderWithSplit(b *testing.B) { | |
| // run the Fib function b.N times | |
| cases := []struct { | |
| name string | |
| header string | |
| }{ | |
| {"sampling", "d"}, | |
| {"traceID_spanID", "000000000000007b00000000000001c8-000000000000007b"}, | |
| {"traceID_spanID_sampling", "000000000000007b00000000000001c8-000000000000007b-1"}, | |
| {"traceID_spanID_sampling_parentID", "000000000000007b00000000000001c8-000000000000007b-1-00000000000001c"}, | |
| } | |
| b.ResetTimer() | |
| for _, c := range cases { | |
| b.Run(c.name, func(b *testing.B) { | |
| for n := 0; n < b.N; n++ { | |
| ParseSingleHeaderWithSplit(c.header) | |
| } | |
| }) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package b3 | |
| import ( | |
| "strconv" | |
| "strings" | |
| "github.com/openzipkin/zipkin-go/model" | |
| ) | |
| func ParseSingleHeader(contextHeader string) (*model.SpanContext, error) { | |
| if contextHeader == "" { | |
| return nil, ErrEmptyContext | |
| } | |
| var ( | |
| sc = model.SpanContext{} | |
| sampling string | |
| ) | |
| headerLen := len(contextHeader) | |
| if headerLen == 1 { | |
| sampling = contextHeader | |
| } else if headerLen == 16 || headerLen == 32 { | |
| return nil, ErrInvalidScope | |
| } else if headerLen >= 16+16+1 { | |
| var high, low uint64 | |
| pos := 0 | |
| if string(contextHeader[16]) != "-" { | |
| // traceID must be 128 bits | |
| var err error | |
| high, err = strconv.ParseUint(contextHeader[0:16], 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| pos = 16 | |
| } | |
| low, err := strconv.ParseUint(contextHeader[pos+1:pos+16], 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| sc.TraceID = model.TraceID{High: high, Low: low} | |
| rawID, err := strconv.ParseUint(contextHeader[pos+16+1:pos+16+1+16], 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidSpanIDValue | |
| } | |
| sc.ID = model.ID(rawID) | |
| if headerLen > pos+16+1+16 { | |
| if headerLen == pos+16+1+16+1 { | |
| return nil, ErrInvalidSampledByte | |
| } | |
| if headerLen == pos+16+1+16+1+1 { | |
| sampling = string(contextHeader[pos+16+1+16+1]) | |
| } else if headerLen == pos+16+1+16+1+16 { | |
| return nil, ErrInvalidScopeParentSingle | |
| } else if headerLen == pos+16+1+16+1+1+1+16 { | |
| sampling = string(contextHeader[pos+16+1+16+1]) | |
| rawParentID, err := strconv.ParseUint(contextHeader[pos+16+1+16+1+1+1:], 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidParentSpanIDValue | |
| } | |
| parentID := model.ID(rawParentID) | |
| sc.ParentID = &parentID | |
| } else { | |
| return nil, ErrInvalidParentSpanIDValue | |
| } | |
| } | |
| } else { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| switch sampling { | |
| case "d": | |
| sc.Debug = true | |
| case "1": | |
| trueVal := true | |
| sc.Sampled = &trueVal | |
| case "0": | |
| falseVal := false | |
| sc.Sampled = &falseVal | |
| case "": | |
| default: | |
| return nil, ErrInvalidSampledByte | |
| } | |
| return &sc, nil | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| func ParseSingleHeader(contextHeader string) (*model.SpanContext, error) { | |
| if contextHeader == "" { | |
| return nil, ErrEmptyContext | |
| } | |
| chunks := strings.SplitN(contextHeader, "-", 4) | |
| var ( | |
| traceID string | |
| spanID string | |
| sampling string | |
| parentSpanID string | |
| sc = model.SpanContext{} | |
| ) | |
| if len(chunks) == 1 { | |
| if len(chunks[0]) == 1 { | |
| sampling = chunks[0] | |
| } else { | |
| return nil, ErrInvalidScope | |
| } | |
| } | |
| if len(chunks) == 2 { | |
| traceID = chunks[0] | |
| spanID = chunks[1] | |
| } | |
| if len(chunks) == 3 { | |
| traceID = chunks[0] | |
| spanID = chunks[1] | |
| sampling = chunks[2] | |
| if chunks[2] == "" { | |
| return nil, ErrInvalidSampledByte | |
| } else if len(chunks[2]) > 1 { | |
| return nil, ErrInvalidScopeParentSingle | |
| } | |
| } | |
| if len(chunks) == 4 { | |
| traceID = chunks[0] | |
| spanID = chunks[1] | |
| sampling = chunks[2] | |
| parentSpanID = chunks[3] | |
| } | |
| switch sampling { | |
| case "d": | |
| sc.Debug = true | |
| case "1": | |
| trueVal := true | |
| sc.Sampled = &trueVal | |
| case "0": | |
| falseVal := false | |
| sc.Sampled = &falseVal | |
| case "": | |
| default: | |
| return nil, ErrInvalidSampledByte | |
| } | |
| if traceID == "" { | |
| return &sc, nil | |
| } | |
| if spanID == "" { | |
| return nil, ErrInvalidScope | |
| } | |
| var err error | |
| pos := 0 | |
| if len(traceID) > 32 { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| if len(traceID) == 32 { | |
| sc.TraceID.High, err = strconv.ParseUint(traceID[0:16], 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| pos = 16 | |
| } else if len(traceID) != 16 { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| sc.TraceID.Low, err = strconv.ParseUint(traceID[pos+1:pos+16], 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidTraceIDValue | |
| } | |
| if len(spanID) != 0 && len(spanID) != 16 { | |
| return nil, ErrInvalidSpanIDValue | |
| } | |
| rawID, err := strconv.ParseUint(spanID, 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidSpanIDValue | |
| } | |
| sc.ID = model.ID(rawID) | |
| if len(parentSpanID) != 0 && len(parentSpanID) != 16 { | |
| return nil, ErrInvalidParentSpanIDValue | |
| } | |
| if parentSpanID != "" { | |
| rawParentID, err := strconv.ParseUint(parentSpanID, 16, 64) | |
| if err != nil { | |
| return nil, ErrInvalidParentSpanIDValue | |
| } | |
| parentID := model.ID(rawParentID) | |
| sc.ParentID = &parentID | |
| } | |
| return &sc, nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment