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

CASSGO-43: externally-defined type registration #1855

Open
wants to merge 1 commit into
base: trunk
Choose a base branch
from

Conversation

jameshartig
Copy link
Contributor

@jameshartig jameshartig commented Jan 2, 2025

CASSGO-43: externally-defined type registration

The new RegisterType function can be used to register externally-defined
types. You'll need to define your own marshalling and unmarshalling code
as well as a TypeInfo implementation. The name and id MUST not collide
with existing and future native CQL types.

A lot of the type handling was refactored to use the new format for
native types.

Pointers to empty interfaces are accepted by Scan and are used to build
the maps in MapScan and SliceMap.

inet columns are now unmarshaled as net.IP which is a breaking change.

goos: linux
goarch: amd64
pkg: github.com/gocql/gocql
cpu: AMD EPYC 7B13
                             │    old.txt    │                new.txt                │
                             │    sec/op     │    sec/op      vs base                │
SingleConn-16                   25.92µ ±  1%    25.74µ ±  1%        ~ (p=0.481 n=10)
ParseRowsFrame-16              1053.5n ±  2%    737.1n ±  1%  -30.03% (p=0.000 n=10)
Unmarshal_BigInt-16             18.91n ±  0%    21.67n ±  0%  +14.60% (p=0.000 n=10)
Unmarshal_Blob-16               19.38n ±  0%    21.62n ±  1%  +11.56% (p=0.000 n=10)
Unmarshal_Boolean-16            16.57n ±  0%    19.20n ±  1%  +15.84% (p=0.000 n=10)
Unmarshal_Date-16               18.48n ±  0%    25.71n ±  1%  +39.15% (p=0.000 n=10)
Unmarshal_Decimal-16            196.5n ±  2%    206.9n ±  1%   +5.32% (p=0.000 n=10)
Unmarshal_Double-16             16.27n ±  1%    18.57n ±  1%  +14.14% (p=0.000 n=10)
Unmarshal_Duration-16           28.55n ±  0%    29.23n ±  0%   +2.40% (p=0.000 n=10)
Unmarshal_Float-16              16.65n ±  1%    18.83n ±  0%  +13.09% (p=0.000 n=10)
Unmarshal_Int-16                19.47n ±  1%    22.92n ±  1%  +17.72% (p=0.000 n=10)
Unmarshal_Inet-16               30.28n ±  1%    41.27n ±  0%  +36.27% (p=0.000 n=10)
Unmarshal_SmallInt-16           19.09n ±  0%    21.93n ±  1%  +14.91% (p=0.000 n=10)
Unmarshal_Time-16               16.57n ±  0%    18.80n ±  0%  +13.39% (p=0.000 n=10)
Unmarshal_Timestamp-16          16.60n ±  0%    18.80n ±  1%  +13.22% (p=0.000 n=10)
Unmarshal_TinyInt-16            16.66n ±  0%    22.61n ±  1%  +35.73% (p=0.000 n=10)
Unmarshal_UUID-16               17.87n ±  0%    19.12n ±  1%   +6.97% (p=0.000 n=10)
Unmarshal_Varchar-16            18.77n ±  1%    21.62n ±  1%  +15.24% (p=0.000 n=10)
Unmarshal_List-16               217.1n ±  0%    222.0n ±  1%   +2.28% (p=0.000 n=10)
Unmarshal_Set-16                219.5n ±  1%    221.3n ±  1%   +0.82% (p=0.001 n=10)
Unmarshal_Map-16                392.7n ±  1%    403.0n ±  1%   +2.62% (p=0.000 n=10)
FramerReadTypeInfo-16           224.7n ±  4%    228.5n ±  1%        ~ (p=0.138 n=10)
ConnStress-16                   9.255µ ± 15%   10.312µ ± 10%  +11.42% (p=0.006 n=10)
ConnRoutingKey-16               178.4n ±  3%    211.7n ±  1%  +18.60% (p=0.000 n=10)
WikiCreateSchema-16             520.9m ±  3%    555.3m ±  3%   +6.62% (p=0.000 n=10)
WikiCreatePages-16              1.492m ±  1%    1.504m ±  2%        ~ (p=0.165 n=10)
WikiSelectAllPages-16           1.959m ±  1%    1.998m ±  3%        ~ (p=0.075 n=10)
WikiSelectSinglePage-16         1.496m ±  1%    1.510m ±  1%        ~ (p=0.052 n=10)
WikiSelectPageCount-16          1.658m ±  2%    1.674m ±  1%        ~ (p=0.075 n=10)
Unmarshal_TupleStrings-16                       401.6n ±  1%
Unmarshal_TupleInterfaces-16                    424.2n ±  1%
geomean                         502.2n          538.0n         +9.11%

                             │    old.txt     │                new.txt                 │
                             │      B/op      │     B/op      vs base                  │
SingleConn-16                  3.110Ki ± 0%     3.110Ki ± 0%        ~ (p=0.224 n=10)
ParseRowsFrame-16               1112.0 ± 0%       856.0 ± 0%  -23.02% (p=0.000 n=10)
Unmarshal_BigInt-16              0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Blob-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Boolean-16             0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Date-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Decimal-16             96.00 ± 0%       96.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Double-16              0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Duration-16            0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Float-16               0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Int-16                 0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Inet-16                4.000 ± 0%       4.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_SmallInt-16            0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Time-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Timestamp-16           0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_TinyInt-16             0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_UUID-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Varchar-16             0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_List-16                32.00 ± 0%       32.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Set-16                 32.00 ± 0%       32.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Map-16                 248.0 ± 0%       248.0 ± 0%        ~ (p=1.000 n=10) ¹
FramerReadTypeInfo-16           160.00 ± 0%       96.00 ± 0%  -40.00% (p=0.000 n=10)
ConnStress-16                  2.670Ki ± 0%     2.667Ki ± 0%        ~ (p=0.068 n=10)
ConnRoutingKey-16                32.00 ± 0%       32.00 ± 0%        ~ (p=1.000 n=10) ¹
WikiCreateSchema-16            53.38Ki ± 1%     53.03Ki ± 1%   -0.65% (p=0.045 n=10)
WikiCreatePages-16             3.866Ki ± 0%     3.864Ki ± 0%        ~ (p=0.563 n=10)
WikiSelectAllPages-16          28.74Ki ± 0%     28.74Ki ± 0%        ~ (p=1.000 n=10)
WikiSelectSinglePage-16        3.305Ki ± 0%     3.303Ki ± 0%        ~ (p=0.426 n=10)
WikiSelectPageCount-16         2.816Ki ± 0%     2.815Ki ± 0%        ~ (p=0.319 n=10)
Unmarshal_TupleStrings-16                         126.0 ± 0%
Unmarshal_TupleInterfaces-16                      126.0 ± 0%
geomean                                     ²                  -2.66%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                             │   old.txt    │               new.txt                │
                             │  allocs/op   │ allocs/op   vs base                  │
SingleConn-16                  37.00 ± 0%     37.00 ± 0%        ~ (p=1.000 n=10) ¹
ParseRowsFrame-16              21.00 ± 0%     13.00 ± 0%  -38.10% (p=0.000 n=10)
Unmarshal_BigInt-16            0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Blob-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Boolean-16           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Date-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Decimal-16           4.000 ± 0%     4.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Double-16            0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Duration-16          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Float-16             0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Int-16               0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Inet-16              1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_SmallInt-16          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Time-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Timestamp-16         0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_TinyInt-16           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_UUID-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Varchar-16           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_List-16              2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Set-16               2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Map-16               5.000 ± 0%     5.000 ± 0%        ~ (p=1.000 n=10) ¹
FramerReadTypeInfo-16          4.000 ± 0%     4.000 ± 0%        ~ (p=1.000 n=10) ¹
ConnStress-16                  33.00 ± 0%     33.00 ± 0%        ~ (p=1.000 n=10)
ConnRoutingKey-16              3.000 ± 0%     3.000 ± 0%        ~ (p=1.000 n=10) ¹
WikiCreateSchema-16            773.0 ± 1%     663.5 ± 1%  -14.17% (p=0.000 n=10)
WikiCreatePages-16             51.00 ± 2%     51.00 ± 2%        ~ (p=0.628 n=10)
WikiSelectAllPages-16          338.0 ± 0%     338.0 ± 0%        ~ (p=1.000 n=10) ¹
WikiSelectSinglePage-16        45.00 ± 0%     45.00 ± 0%        ~ (p=1.000 n=10) ¹
WikiSelectPageCount-16         40.00 ± 0%     40.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_TupleStrings-16                     8.000 ± 0%
Unmarshal_TupleInterfaces-16                  8.000 ± 0%
geomean                                   ²                -2.16%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

@jameshartig
Copy link
Contributor Author

jameshartig commented Jan 3, 2025

Here's an example of a JSONB type:

package mypackage

import "github.com/gocql/gocql"

var typeJSONB gocql.Type = 0x0080

func init() {
	gocql.RegisterType(typeJSONB, "jsonb", jsonbCQLType{})
}

// jsonbCQLType implements the gocql.CQLType interface
type jsonbCQLType struct {
}

// Params implements the gocql.CQLType interface
func (j jsonbCQLType) Params(proto int) []reflect.Type {
	return nil
}

// TypeInfoFromParams implements the gocql.CQLType interface
func (j jsonbCQLType) TypeInfoFromParams(proto int, params []interface{}) TypeInfo {
	if len(params) != 0 {
		panic(fmt.Errorf("expected 0 param for jsonb type, got %d", len(params)))
	}
	return typeJSONB
}

// TypeInfoFromString implements the gocql.CQLType interface
func (j jsonbCQLType) TypeInfoFromString(proto int, name string) TypeInfo {
	if name != "" {
		panic(fmt.Errorf("expected empty name for jsonb type, got %s", name))
	}
	return typeJSONB
}

// Marshal implements the gocql.CQLType interface
func (j jsonbCQLType) Marshal(info gocql.TypeInfo, value interface{}) ([]byte, error) {
	return gocql.Marshal(gocql.TypeBlob, value)
}

// Unmarshal implements the gocql.CQLType interface
func (j jsonbCQLType) Unmarshal(info gocql.TypeInfo, value []byte, dest interface{}) error {
	return gocql.Unmarshal(gocql.TypeBlob, value, dest)
}

Or they can write their own marshal/unmarshal methods:

func marshalJSONB(info gocql.TypeInfo, value interface{}) ([]byte, error) {
	switch v := value.(type) {
	case gocql.Marshaler:
		return v.MarshalCQL(info)
	case json.RawMessage:
		return v, nil
	case string:
		return []byte(v), nil
	case []byte:
		return v, nil
	}
	if value == nil {
		return nil, nil
	}

	rv := reflect.ValueOf(value)
	t := rv.Type()
	k := t.Kind()
	switch {
	case k == reflect.String:
		return []byte(rv.String()), nil
	case k == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
		return rv.Bytes(), nil
	}
	return nil, gocql.MarshalError(fmt.Sprintf("can not marshal %T into jsonb", value))
}

var typeSliceOfBytes = reflect.TypeOf([]byte(nil))

func unmarshalJSONB(info gocql.TypeInfo, data []byte, value interface{}) error {
	switch v := value.(type) {
	case gocql.Unmarshaler:
		return v.UnmarshalCQL(info, data)
	case *json.RawMessage:
		if data != nil {
			*v = append((*v)[:0], data...)
		} else {
			*v = nil
		}
		return nil
	case *string:
		*v = string(data)
		return nil
	case *[]byte:
		if data != nil {
			*v = append((*v)[:0], data...)
		} else {
			*v = nil
		}
		return nil
	case *interface{}:
		if data != nil {
			*v = append(json.RawMessage{}, data...)
		} else {
			*v = nil
		}
		return nil

	}

	rv := reflect.ValueOf(value)
	if rv.Kind() != reflect.Ptr {
		return gocql.UnmarshalError(fmt.Sprintf("can not unmarshal jsonb into non-pointer %T", value))
	}
	rv = rv.Elem()
	t := rv.Type()
	k := t.Kind()
	switch {
	case k == reflect.String:
		rv.SetString(string(data))
		return nil
	case k == reflect.Slice && t.Elem().Kind() == reflect.Uint8:
		if data != nil {
			if rv.Type() != typeSliceOfBytes {
				rv.Set(reflect.AppendSlice(rv.Slice(0, 0), reflect.ValueOf(data).Convert(t)))
			} else {
				rv.Set(reflect.AppendSlice(rv.Slice(0, 0), reflect.ValueOf(data)))
			}
		} else {
			rv.Set(reflect.Zero(t))
		}
		return nil
	}
	return gocql.UnmarshalError(fmt.Sprintf("can not unmarshal jsonb into %T", value))
}

@jameshartig
Copy link
Contributor Author

I could use some tests of custom types but given that all of the native types are using most of the same code, I feel confident in the guts of the code.

@jameshartig jameshartig force-pushed the external-types branch 2 times, most recently from 1c53a5b to 0203176 Compare January 31, 2025 08:05
@joao-r-reis
Copy link
Contributor

This looks great! #1828 has been waiting to be merged for a while and it looks like the code changes might conflict with some of the changes here on this PR so I'd like to get #1828 merged before this one unless there's benefits to mergind this one first

@jameshartig
Copy link
Contributor Author

This looks great! #1828 has been waiting to be merged for a while and it looks like the code changes might conflict with some of the changes here on this PR so I'd like to get #1828 merged before this one unless there's benefits to mergind this one first

That makes sense. Going to switch this back to draft so I can resolve those conflicts and take a stab at cleaning up the UDT case we talked about in Slack.

@jameshartig jameshartig marked this pull request as draft January 31, 2025 15:17
@jameshartig
Copy link
Contributor Author

I simplified the TypeInfo struct but had to keep it around so that composite types could store their children type info somewhere. Simple types can just use their Type as a TypeInfo though. This reduced the boilerplate necessary to add a new type (I updated the above jsonb example) and allowed me to remove the separate composite interface and only have a single interface that's necessary to implement.

@jameshartig
Copy link
Contributor Author

Initially, some of the unmarshal benchmarks were worse so I inlined some of the type switching which is a bit gross but massively improved the benchmarks.

@jameshartig jameshartig force-pushed the external-types branch 3 times, most recently from 4ce416c to 88ed1af Compare February 5, 2025 06:56
The new RegisterType function can be used to register externally-defined
types. You'll need to define your own marshalling and unmarshalling code
as well as a TypeInfo implementation. The name and id MUST not collide
with existing and future native CQL types.

A lot of the type handling was refactored to use the new format for
native types.

Pointers to empty interfaces are accepted by Scan and are used to build
the maps in MapScan and SliceMap.

inet columns are now unmarshaled as net.IP which is a breaking change.

goos: linux
goarch: amd64
pkg: github.com/gocql/gocql
cpu: AMD EPYC 7B13
                             │    old.txt    │                new.txt                │
                             │    sec/op     │    sec/op      vs base                │
SingleConn-16                   25.92µ ±  1%    25.74µ ±  1%        ~ (p=0.481 n=10)
ParseRowsFrame-16              1053.5n ±  2%    737.1n ±  1%  -30.03% (p=0.000 n=10)
Unmarshal_BigInt-16             18.91n ±  0%    21.67n ±  0%  +14.60% (p=0.000 n=10)
Unmarshal_Blob-16               19.38n ±  0%    21.62n ±  1%  +11.56% (p=0.000 n=10)
Unmarshal_Boolean-16            16.57n ±  0%    19.20n ±  1%  +15.84% (p=0.000 n=10)
Unmarshal_Date-16               18.48n ±  0%    25.71n ±  1%  +39.15% (p=0.000 n=10)
Unmarshal_Decimal-16            196.5n ±  2%    206.9n ±  1%   +5.32% (p=0.000 n=10)
Unmarshal_Double-16             16.27n ±  1%    18.57n ±  1%  +14.14% (p=0.000 n=10)
Unmarshal_Duration-16           28.55n ±  0%    29.23n ±  0%   +2.40% (p=0.000 n=10)
Unmarshal_Float-16              16.65n ±  1%    18.83n ±  0%  +13.09% (p=0.000 n=10)
Unmarshal_Int-16                19.47n ±  1%    22.92n ±  1%  +17.72% (p=0.000 n=10)
Unmarshal_Inet-16               30.28n ±  1%    41.27n ±  0%  +36.27% (p=0.000 n=10)
Unmarshal_SmallInt-16           19.09n ±  0%    21.93n ±  1%  +14.91% (p=0.000 n=10)
Unmarshal_Time-16               16.57n ±  0%    18.80n ±  0%  +13.39% (p=0.000 n=10)
Unmarshal_Timestamp-16          16.60n ±  0%    18.80n ±  1%  +13.22% (p=0.000 n=10)
Unmarshal_TinyInt-16            16.66n ±  0%    22.61n ±  1%  +35.73% (p=0.000 n=10)
Unmarshal_UUID-16               17.87n ±  0%    19.12n ±  1%   +6.97% (p=0.000 n=10)
Unmarshal_Varchar-16            18.77n ±  1%    21.62n ±  1%  +15.24% (p=0.000 n=10)
Unmarshal_List-16               217.1n ±  0%    222.0n ±  1%   +2.28% (p=0.000 n=10)
Unmarshal_Set-16                219.5n ±  1%    221.3n ±  1%   +0.82% (p=0.001 n=10)
Unmarshal_Map-16                392.7n ±  1%    403.0n ±  1%   +2.62% (p=0.000 n=10)
FramerReadTypeInfo-16           224.7n ±  4%    228.5n ±  1%        ~ (p=0.138 n=10)
ConnStress-16                   9.255µ ± 15%   10.312µ ± 10%  +11.42% (p=0.006 n=10)
ConnRoutingKey-16               178.4n ±  3%    211.7n ±  1%  +18.60% (p=0.000 n=10)
WikiCreateSchema-16             520.9m ±  3%    555.3m ±  3%   +6.62% (p=0.000 n=10)
WikiCreatePages-16              1.492m ±  1%    1.504m ±  2%        ~ (p=0.165 n=10)
WikiSelectAllPages-16           1.959m ±  1%    1.998m ±  3%        ~ (p=0.075 n=10)
WikiSelectSinglePage-16         1.496m ±  1%    1.510m ±  1%        ~ (p=0.052 n=10)
WikiSelectPageCount-16          1.658m ±  2%    1.674m ±  1%        ~ (p=0.075 n=10)
Unmarshal_TupleStrings-16                       401.6n ±  1%
Unmarshal_TupleInterfaces-16                    424.2n ±  1%
geomean                         502.2n          538.0n         +9.11%

                             │    old.txt     │                new.txt                 │
                             │      B/op      │     B/op      vs base                  │
SingleConn-16                  3.110Ki ± 0%     3.110Ki ± 0%        ~ (p=0.224 n=10)
ParseRowsFrame-16               1112.0 ± 0%       856.0 ± 0%  -23.02% (p=0.000 n=10)
Unmarshal_BigInt-16              0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Blob-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Boolean-16             0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Date-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Decimal-16             96.00 ± 0%       96.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Double-16              0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Duration-16            0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Float-16               0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Int-16                 0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Inet-16                4.000 ± 0%       4.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_SmallInt-16            0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Time-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Timestamp-16           0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_TinyInt-16             0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_UUID-16                0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Varchar-16             0.000 ± 0%       0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_List-16                32.00 ± 0%       32.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Set-16                 32.00 ± 0%       32.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Map-16                 248.0 ± 0%       248.0 ± 0%        ~ (p=1.000 n=10) ¹
FramerReadTypeInfo-16           160.00 ± 0%       96.00 ± 0%  -40.00% (p=0.000 n=10)
ConnStress-16                  2.670Ki ± 0%     2.667Ki ± 0%        ~ (p=0.068 n=10)
ConnRoutingKey-16                32.00 ± 0%       32.00 ± 0%        ~ (p=1.000 n=10) ¹
WikiCreateSchema-16            53.38Ki ± 1%     53.03Ki ± 1%   -0.65% (p=0.045 n=10)
WikiCreatePages-16             3.866Ki ± 0%     3.864Ki ± 0%        ~ (p=0.563 n=10)
WikiSelectAllPages-16          28.74Ki ± 0%     28.74Ki ± 0%        ~ (p=1.000 n=10)
WikiSelectSinglePage-16        3.305Ki ± 0%     3.303Ki ± 0%        ~ (p=0.426 n=10)
WikiSelectPageCount-16         2.816Ki ± 0%     2.815Ki ± 0%        ~ (p=0.319 n=10)
Unmarshal_TupleStrings-16                         126.0 ± 0%
Unmarshal_TupleInterfaces-16                      126.0 ± 0%
geomean                                     ²                  -2.66%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                             │   old.txt    │               new.txt                │
                             │  allocs/op   │ allocs/op   vs base                  │
SingleConn-16                  37.00 ± 0%     37.00 ± 0%        ~ (p=1.000 n=10) ¹
ParseRowsFrame-16              21.00 ± 0%     13.00 ± 0%  -38.10% (p=0.000 n=10)
Unmarshal_BigInt-16            0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Blob-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Boolean-16           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Date-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Decimal-16           4.000 ± 0%     4.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Double-16            0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Duration-16          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Float-16             0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Int-16               0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Inet-16              1.000 ± 0%     1.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_SmallInt-16          0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Time-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Timestamp-16         0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_TinyInt-16           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_UUID-16              0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Varchar-16           0.000 ± 0%     0.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_List-16              2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Set-16               2.000 ± 0%     2.000 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_Map-16               5.000 ± 0%     5.000 ± 0%        ~ (p=1.000 n=10) ¹
FramerReadTypeInfo-16          4.000 ± 0%     4.000 ± 0%        ~ (p=1.000 n=10) ¹
ConnStress-16                  33.00 ± 0%     33.00 ± 0%        ~ (p=1.000 n=10)
ConnRoutingKey-16              3.000 ± 0%     3.000 ± 0%        ~ (p=1.000 n=10) ¹
WikiCreateSchema-16            773.0 ± 1%     663.5 ± 1%  -14.17% (p=0.000 n=10)
WikiCreatePages-16             51.00 ± 2%     51.00 ± 2%        ~ (p=0.628 n=10)
WikiSelectAllPages-16          338.0 ± 0%     338.0 ± 0%        ~ (p=1.000 n=10) ¹
WikiSelectSinglePage-16        45.00 ± 0%     45.00 ± 0%        ~ (p=1.000 n=10) ¹
WikiSelectPageCount-16         40.00 ± 0%     40.00 ± 0%        ~ (p=1.000 n=10) ¹
Unmarshal_TupleStrings-16                     8.000 ± 0%
Unmarshal_TupleInterfaces-16                  8.000 ± 0%
geomean                                   ²                -2.16%                ²
¹ all samples are equal
² summaries must be >0 to compute geomean

Patch by James Hartig for CASSGO-43
@jameshartig
Copy link
Contributor Author

Initially, some of the unmarshal benchmarks were worse so I inlined some of the type switching which is a bit gross but massively improved the benchmarks.

I do think we can roll some of those back when Go 1.24 comes out and there's improved Swiss table maps. I'll need to rerun the benchmarks but it would be nice to get rid of all of that boilerplate.

@joao-r-reis
Copy link
Contributor

I do think we can roll some of those back when Go 1.24 comes out and there's improved Swiss table maps. I'll need to rerun the benchmarks but it would be nice to get rid of all of that boilerplate.

We probably want to be careful with requiring such a recent go version, if it's not crucial then we should delay it as much as possible

@joao-r-reis
Copy link
Contributor

Is this ready for review btw?

@jameshartig
Copy link
Contributor Author

Is this ready for review btw?

Yes, but I would like a chance to write some more tests. I think it's in a good place though for review besides the tests.

We probably want to be careful with requiring such a recent go version, if it's not crucial then we should delay it as much as possible

Yeah, my comment was meant for the distant future.

@jameshartig jameshartig marked this pull request as ready for review February 22, 2025 04:30
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.

2 participants