Skip to content

sql/catalog/descs: implement interfaces on *DistSQLTypeResolver#72962

Merged
craig[bot] merged 1 commit intocockroachdb:masterfrom
nvb:nvanbenschoten/typeResInterface
Nov 19, 2021
Merged

sql/catalog/descs: implement interfaces on *DistSQLTypeResolver#72962
craig[bot] merged 1 commit intocockroachdb:masterfrom
nvb:nvanbenschoten/typeResInterface

Conversation

@nvb
Copy link
Copy Markdown
Contributor

@nvb nvb commented Nov 19, 2021

This commit updates DistSQLTypeResolver to implement all interfaces on a
pointer receiver instead of a value receiver. Implementing interfaces on values
is rarely the right choice, as it forces a heap allocation whenever the object
is boxed into an interface, instead of just forcing the pointer onto the heap
once (on its own or as part of a larger object) and then storing the pointer in
the interface header.

Before this commit, the use of value receivers was causing HydrateTypeSlice to
allocate. Outside of #72798 and #72961, this was the single largest source of
heap allocations in TPC-E. With those two PRs applied, HydrateTypeSlice was
accounting for 2.30% of total heap allocations in the workload:

----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          27722149 32.66% |   github.com/cockroachdb/cockroach/pkg/sql/execinfra.(*ProcessorBase).InitWithEvalCtx /go/src/github.com/cockroachdb/cockroach/pkg/sql/execinfra/processorsbase.go:790
                                          27460002 32.36% |   github.com/cockroachdb/cockroach/pkg/sql/colflow.(*vectorizedFlowCreator).setupFlow.func1 /go/src/github.com/cockroachdb/cockroach/pkg/sql/colflow/vectorized_flow.go:1097
                                          21266755 25.06% |   github.com/cockroachdb/cockroach/pkg/sql/colflow.(*vectorizedFlowCreator).setupInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/colflow/vectorized_flow.go:818
                                           8421503  9.92% |   github.com/cockroachdb/cockroach/pkg/sql/colfetcher.populateTableArgs /go/src/github.com/cockroachdb/cockroach/pkg/sql/colfetcher/cfetcher_setup.go:174
  84870409  2.30%  2.30%   84870409  2.30%                | github.com/cockroachdb/cockroach/pkg/sql/catalog/descs.DistSQLTypeResolver.HydrateTypeSlice /go/src/github.com/cockroachdb/cockroach/pkg/sql/catalog/descs/dist_sql_type_resolver.go:134
----------------------------------------------------------+-------------

With this change, the heap allocation in HydrateTypeSlice disappears.

With these three PRs combined, the largest source of heap allocations in the
workload is context.WithValue, like the Go gods intended.

----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          16723340 38.17% |   github.com/cockroachdb/logtags.WithTags /go/src/github.com/cockroachdb/cockroach/vendor/github.com/cockroachdb/logtags/context.go:34
                                           7405899 16.90% |   google.golang.org/grpc/peer.NewContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/peer/peer.go:44
                                           3910493  8.93% |   google.golang.org/grpc.NewContextWithServerTransportStream /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/server.go:1672
                                           3702950  8.45% |   github.com/cockroachdb/cockroach/pkg/util/tracing.maybeWrapCtx /go/src/github.com/cockroachdb/cockroach/pkg/util/tracing/context.go:80
                                           3560952  8.13% |   google.golang.org/grpc/metadata.NewIncomingContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/metadata/metadata.go:152
                                           3342479  7.63% |   google.golang.org/grpc.newContextWithRPCInfo /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/rpc_util.go:791
                                           2938326  6.71% |   google.golang.org/grpc/internal/credentials.NewRequestInfoContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/internal/credentials/credentials.go:29
                                           1387235  3.17% |   github.com/cockroachdb/cockroach/pkg/util/grpcutil.NewLocalRequestContext /go/src/github.com/cockroachdb/cockroach/pkg/util/grpcutil/grpc_util.go:39
                                            655388  1.50% |   github.com/cockroachdb/cockroach/pkg/sql.withStatement /go/src/github.com/cockroachdb/cockroach/pkg/sql/conn_executor.go:3197
                                            185693  0.42% |   google.golang.org/grpc/metadata.NewOutgoingContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/metadata/metadata.go:159
  43812755  2.20%  2.20%   43812755  2.20%                | context.WithValue /usr/local/go/src/context/context.go:533
----------------------------------------------------------+-------------

This commit updates `DistSQLTypeResolver` to implement all interfaces on a
pointer receiver instead of a value receiver. Implementing interfaces on values
is rarely the right choice, as it forces a heap allocation whenever the object
is boxed into an interface, instead of just forcing the pointer onto the heap
once (on its own or as part of a larger object) and then storing the pointer in
the interface header.

Before this commit, the use of value receivers was causing `HydrateTypeSlice` to
allocate. Outside of cockroachdb#72798 and cockroachdb#72961, this was the single largest source of
heap allocations in TPC-E. With those two PRs applied, `HydrateTypeSlice` was
accounting for **2.30%** of total heap allocations in the workload:

```
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          27722149 32.66% |   github.com/cockroachdb/cockroach/pkg/sql/execinfra.(*ProcessorBase).InitWithEvalCtx /go/src/github.com/cockroachdb/cockroach/pkg/sql/execinfra/processorsbase.go:790
                                          27460002 32.36% |   github.com/cockroachdb/cockroach/pkg/sql/colflow.(*vectorizedFlowCreator).setupFlow.func1 /go/src/github.com/cockroachdb/cockroach/pkg/sql/colflow/vectorized_flow.go:1097
                                          21266755 25.06% |   github.com/cockroachdb/cockroach/pkg/sql/colflow.(*vectorizedFlowCreator).setupInput /go/src/github.com/cockroachdb/cockroach/pkg/sql/colflow/vectorized_flow.go:818
                                           8421503  9.92% |   github.com/cockroachdb/cockroach/pkg/sql/colfetcher.populateTableArgs /go/src/github.com/cockroachdb/cockroach/pkg/sql/colfetcher/cfetcher_setup.go:174
  84870409  2.30%  2.30%   84870409  2.30%                | github.com/cockroachdb/cockroach/pkg/sql/catalog/descs.DistSQLTypeResolver.HydrateTypeSlice /go/src/github.com/cockroachdb/cockroach/pkg/sql/catalog/descs/dist_sql_type_resolver.go:134
----------------------------------------------------------+-------------
```

With this change, the heap allocation in `HydrateTypeSlice` disappears.

With these three PRs combined, the largest source of heap allocations in the
workload is `context.WithValue`, like the Go gods intended.
```
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                          16723340 38.17% |   github.com/cockroachdb/logtags.WithTags /go/src/github.com/cockroachdb/cockroach/vendor/github.com/cockroachdb/logtags/context.go:34
                                           7405899 16.90% |   google.golang.org/grpc/peer.NewContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/peer/peer.go:44
                                           3910493  8.93% |   google.golang.org/grpc.NewContextWithServerTransportStream /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/server.go:1672
                                           3702950  8.45% |   github.com/cockroachdb/cockroach/pkg/util/tracing.maybeWrapCtx /go/src/github.com/cockroachdb/cockroach/pkg/util/tracing/context.go:80
                                           3560952  8.13% |   google.golang.org/grpc/metadata.NewIncomingContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/metadata/metadata.go:152
                                           3342479  7.63% |   google.golang.org/grpc.newContextWithRPCInfo /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/rpc_util.go:791
                                           2938326  6.71% |   google.golang.org/grpc/internal/credentials.NewRequestInfoContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/internal/credentials/credentials.go:29
                                           1387235  3.17% |   github.com/cockroachdb/cockroach/pkg/util/grpcutil.NewLocalRequestContext /go/src/github.com/cockroachdb/cockroach/pkg/util/grpcutil/grpc_util.go:39
                                            655388  1.50% |   github.com/cockroachdb/cockroach/pkg/sql.withStatement /go/src/github.com/cockroachdb/cockroach/pkg/sql/conn_executor.go:3197
                                            185693  0.42% |   google.golang.org/grpc/metadata.NewOutgoingContext /go/src/github.com/cockroachdb/cockroach/vendor/google.golang.org/grpc/metadata/metadata.go:159
  43812755  2.20%  2.20%   43812755  2.20%                | context.WithValue /usr/local/go/src/context/context.go:533
----------------------------------------------------------+-------------
```
@nvb nvb requested review from a team and ajwerner November 19, 2021 02:48
@cockroach-teamcity
Copy link
Copy Markdown
Member

This change is Reviewable

Copy link
Copy Markdown
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajwerner and @nvanbenschoten)


pkg/sql/catalog/descs/dist_sql_type_resolver.go, line 67 at r1 (raw file):

// NewDistSQLTypeResolver creates a new DistSQLTypeResolver.
func NewDistSQLTypeResolver(descs *Collection, txn *kv.Txn) DistSQLTypeResolver {
	return DistSQLTypeResolver{

Should we just make this and the above NewTypeResolver method return a pointer? I feel like the whole path in NewTypeResolver where we return a zero value is a mistake because all the methods on that thing are going to panic.

Copy link
Copy Markdown
Contributor Author

@nvb nvb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajwerner)


pkg/sql/catalog/descs/dist_sql_type_resolver.go, line 67 at r1 (raw file):

Previously, ajwerner wrote…

Should we just make this and the above NewTypeResolver method return a pointer? I feel like the whole path in NewTypeResolver where we return a zero value is a mistake because all the methods on that thing are going to panic.

I was considering that, but noticed that vectorizedFlowCreator stores a descs.DistSQLTypeResolver by value, so it is a case where we are able to avoid a separate heap allocation by returning this by value and then storing it by value it in a larger struct. I'm mostly ambivalent though, so I'll defer to you.

Copy link
Copy Markdown
Contributor

@ajwerner ajwerner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @ajwerner and @nvanbenschoten)


pkg/sql/catalog/descs/dist_sql_type_resolver.go, line 67 at r1 (raw file):

Previously, nvanbenschoten (Nathan VanBenschoten) wrote…

I was considering that, but noticed that vectorizedFlowCreator stores a descs.DistSQLTypeResolver by value, so it is a case where we are able to avoid a separate heap allocation by returning this by value and then storing it by value it in a larger struct. I'm mostly ambivalent though, so I'll defer to you.

Thanks for checking. That's legit enough for me.

@nvb
Copy link
Copy Markdown
Contributor Author

nvb commented Nov 19, 2021

TFTR!

bors r+

@craig
Copy link
Copy Markdown
Contributor

craig bot commented Nov 19, 2021

Build succeeded:

@craig craig bot merged commit e131a82 into cockroachdb:master Nov 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants