Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codec import adds huge bloat #295

Closed
drasko opened this issue May 6, 2019 · 1 comment
Closed

Codec import adds huge bloat #295

drasko opened this issue May 6, 2019 · 1 comment

Comments

@drasko
Copy link

drasko commented May 6, 2019

Looks like codec import makes binaries to be huge:

drasko@Marx:~/go/src/github.com/mainflux/mainflux/cmd/normalizer$ goweight 
   10 MB github.com/mainflux/mainflux/vendor/github.com/ugorji/go/codec
  3.4 MB net/http
  3.0 MB runtime
  2.0 MB github.com/mainflux/mainflux/vendor/github.com/gogo/protobuf/proto
  1.7 MB github.com/mainflux/mainflux/vendor/golang.org/x/net/http2
  1.7 MB net
  1.6 MB github.com/mainflux/mainflux/vendor/github.com/golang/protobuf/proto
  1.4 MB reflect
  1.2 MB github.com/mainflux/mainflux/vendor/google.golang.org/grpc
  1.2 MB github.com/mainflux/mainflux/vendor/github.com/prometheus/client_golang/prometheus/promhttp
  1.0 MB github.com/mainflux/mainflux/vendor/golang.org/x/sys/unix
  1.0 MB github.com/mainflux/mainflux/vendor/github.com/prometheus/client_golang/prometheus
  945 kB github.com/mainflux/mainflux/vendor/google.golang.org/grpc/internal/transport
  933 kB crypto/tls
  872 kB math/big
  753 kB encoding/gob
  714 kB syscall
  633 kB crypto/x509
  627 kB text/template
  596 kB encoding/xml
  574 kB github.com/mainflux/mainflux/vendor/github.com/nats-io/go-nats
  547 kB encoding/json
  510 kB html/template
...

Typically, binary that was expected to be ~3-4MB in size wight now 14MB just because it imports codec.

@ugorji
Copy link
Owner

ugorji commented May 7, 2019

Yes,

Basically, generated code increases the size of the package. Generated code occurs when we generate the fastpath helpers, and when users explicitly use codegeneration.

To override using the fastpath, build with the tag notfastpath.

However, be aware that a significant performance benefits occurs from its use. For example, look at the examples below running benchmarks with and without notfast path:

cd bench
go test -run Nothing -bench Benchmark__Cbor_______Decode -benchmem -benchtime 5s -tags ""
go test -run Nothing -bench Benchmark__Cbor_______Decode -benchmem -benchtime 5s -tags "notfastpath"

results:

Benchmark__Cbor_______Decode-8   	   55899	    103707 ns/op	   35520 B/op	     368 allocs/op
Benchmark__Cbor_______Decode-8   	   41484	    137589 ns/op	   39128 B/op	     500 allocs/op

As you can see, at least in this representative benchmark, we get about 33% increase in time per decode operation. Of course, YMMV. And the reduction in size may be worth it, and also most of the types supported in the fastpath may be unnecessary for your use-case.

@ugorji ugorji closed this as completed May 7, 2019
ugorji added a commit that referenced this issue May 16, 2019
…t.Sort wrappers

We no longer generate fast-paths for maps with
- keys of type int8/16/32, uint16/32, float32/64, bool, interface{}
- values of type int8/16/32, uint16/32

This is in a bid to reduce the binary size for types which depend on go-codec.

Previously, go-codec was adding about 11MB to a binary.
We have now reduce that to 5.7MB.

The user has the option to reduce this further to
2.9MB by passing the tag 'notfastpath' during a build or install.

In addition, we now generate sort.Sort wrappers for types we care about.
This way, we don't have to maintain the code manually.

In generated fast-path and other code, we also reduced the amount of unnecessary
conversions we do.

Updates #295
Updates cisco/senml#22
Fixes #296
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants