Skip to content

Significant performance variation for defining times #510

Open
@jacksontj

Description

@jacksontj

First off, thanks for this amazing library. I have been using this for a few projects and it is simply amazing.

While working on a project I ran into a seemingly confusing performance issue. I need to pass a time around in my rpc messages, my current implementation is using a single int64, but I decided that I'd move to using the google timestamp (int64 + int32) to get better granularity etc. After doing so my benchmarks are showing a significant performance cost for doing so.

As a baseline, doing a single message with an int64 takes 61/38 ns to Marshal/Unmarshal respectively. Doing so with a google.Timestamp is 98/131 (which is ~1.5x/~3x slowdown respectively). I tried a variety of gogo options (stdtime, nullable=false, etc.). From doing those I see 2 patterns:

  1. stdtime always returns a *time.Time which means even in the nullable=false case it seems to be heap allocating -- which is causing some slowdown
  2. having the timestamp in a type within the message is significantly slower

I have created a repo with my test code that these benchmarks where done with. I'll paste the output below here for convenience:

goos: linux
goarch: amd64
pkg: github.com/jacksontj/timestampProto
BenchmarkProto3/marshal/EmbeddedGoogleTimestamp-8                       	20000000	        98.3 ns/op	       4 B/op	       1 allocs/op
BenchmarkProto3/unmarshal/EmbeddedGoogleTimestamp-8       	                10000000	       131 ns/op	      48 B/op	       1 allocs/op
BenchmarkProto3/marshal/EmbeddedGoogleTimestampStdTimeNonNull-8         	 3000000	       450 ns/op	     148 B/op	       4 allocs/op
BenchmarkProto3/unmarshal/EmbeddedGoogleTimestampStdTimeNonNull-8       	10000000	       141 ns/op	      48 B/op	       1 allocs/op
BenchmarkProto3/marshal/MyTimestamp-8                                   	20000000	        66.3 ns/op	       2 B/op	       1 allocs/op
BenchmarkProto3/unmarshal/MyTimestamp-8                                 	50000000	        35.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkProto3/marshal/EmbeddedStdTime-8                               	 3000000	       443 ns/op	     148 B/op	       4 allocs/op
BenchmarkProto3/unmarshal/EmbeddedStdTime-8                             	10000000	       212 ns/op	      80 B/op	       2 allocs/op
BenchmarkProto3/marshal/EmbeddedStdTimeNonNull-8                        	 3000000	       451 ns/op	     148 B/op	       4 allocs/op
BenchmarkProto3/unmarshal/EmbeddedStdTimeNonNull-8                      	10000000	       141 ns/op	      48 B/op	       1 allocs/op
BenchmarkProto3/marshal/EmbeddedGoogleTimestampStdTime-8                	20000000	       100 ns/op	       4 B/op	       1 allocs/op
BenchmarkProto3/unmarshal/EmbeddedGoogleTimestampStdTime-8              	10000000	       127 ns/op	      48 B/op	       1 allocs/op
BenchmarkProto3/marshal/EmbeddedGoogleTimestampNonNull-8                	20000000	        93.0 ns/op	       4 B/op	       1 allocs/op
BenchmarkProto3/unmarshal/EmbeddedGoogleTimestampNonNull-8              	30000000	        49.2 ns/op	       0 B/op	       0 allocs/op
BenchmarkProto3/marshal/Int64-8                                         	20000000	        61.6 ns/op	       2 B/op	       1 allocs/op
BenchmarkProto3/unmarshal/Int64-8                                       	30000000	        38.7 ns/op	       0 B/op	       0 allocs/op
BenchmarkProto3/marshal/Embedded-8                                      	20000000	        90.7 ns/op	       4 B/op	       1 allocs/op
BenchmarkProto3/unmarshal/Embedded-8                                    	20000000	        87.0 ns/op	      16 B/op	       1 allocs/op
PASS

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions