@@ -28,8 +28,9 @@ func Test_ColumnarInsert(t *testing.T) {
2828 enum8 Enum8 ('a' = 1, 'b' = 2),
2929 enum16 Enum16('c' = 1, 'd' = 2),
3030 array Array(String),
31- array2 Array(UInt64),
32- arrayArray Array(Array(String))
31+ arrayArray Array(Array(String)),
32+ arrayWithValue Array(UInt64),
33+ arrayWithValueFast Array(UInt64)
3334 ) Engine=Memory
3435 `
3536 dml = `
@@ -47,8 +48,9 @@ func Test_ColumnarInsert(t *testing.T) {
4748 enum8,
4849 enum16,
4950 array,
50- array2,
51- arrayArray
51+ arrayArray,
52+ arrayWithValue,
53+ arrayWithValueFast
5254 ) VALUES (
5355 ?,
5456 ?,
@@ -108,8 +110,9 @@ func Test_ColumnarInsert(t *testing.T) {
108110 block .WriteUInt8 (10 , 1 )
109111 block .WriteUInt16 (11 , 2 )
110112 block .WriteArray (12 , []string {"A" , "B" , "C" })
111- block .WriteArrayWithValue (13 , uint64SliceValue {value : []uint64 {1 , 2 , 3 }})
112- block .WriteArray (14 , [][]string {[]string {"A" , "B" }, []string {"CC" , "DD" , "EE" }})
113+ block .WriteArray (13 , [][]string {[]string {"A" , "B" }, []string {"CC" , "DD" , "EE" }})
114+ block .WriteArrayWithValue (14 , newUint64SliceValueSimple ([]uint64 {1 , 2 , 3 }))
115+ block .WriteArrayWithValue (15 , newUint64SliceValueFast ([]uint64 {10 , 20 , 30 }))
113116 if ! assert .NoError (t , err ) {
114117 return
115118 }
@@ -126,38 +129,75 @@ type uint64Value struct {
126129 value uint64
127130}
128131
129- func (v uint64Value ) Kind () reflect.Kind {
132+ func (v * uint64Value ) Kind () reflect.Kind {
130133 return reflect .String
131134}
132135
133- func (v uint64Value ) Len () int {
136+ func (v * uint64Value ) Len () int {
134137 panic ("uint64 has no length" )
135138}
136139
137- func (v uint64Value ) Index (i int ) data.Value {
140+ func (v * uint64Value ) Index (i int ) data.Value {
138141 panic ("uint64 has no index" )
139142}
140143
141- func (v uint64Value ) Interface () interface {} {
144+ func (v * uint64Value ) Interface () interface {} {
142145 return v .value
143146}
144147
145- type uint64SliceValue struct {
146- value []uint64
148+ type uint64SliceValueSimple struct {
149+ uint64Slice []uint64
147150}
148151
149- func (v uint64SliceValue ) Kind () reflect.Kind {
152+ func newUint64SliceValueSimple (v []uint64 ) * uint64SliceValueSimple {
153+ return & uint64SliceValueSimple {uint64Slice : v }
154+ }
155+
156+ func (v * uint64SliceValueSimple ) Kind () reflect.Kind {
150157 return reflect .Slice
151158}
152159
153- func (v uint64SliceValue ) Len () int {
154- return len (v .value )
160+ func (v * uint64SliceValueSimple ) Len () int {
161+ return len (v .uint64Slice )
162+ }
163+
164+ func (v * uint64SliceValueSimple ) Index (i int ) data.Value {
165+ return & uint64Value {value : v .uint64Slice [i ]}
166+ }
167+
168+ func (v * uint64SliceValueSimple ) Interface () interface {} {
169+ return v .uint64Slice
170+ }
171+
172+ type uint64SliceValueFast struct {
173+ uint64Slice []uint64
174+ uint64Value * uint64Value
175+ value data.Value
155176}
156177
157- func (v uint64SliceValue ) Index (i int ) data.Value {
158- return uint64Value {value : v .value [i ]}
178+ func newUint64SliceValueFast (v []uint64 ) * uint64SliceValueFast {
179+ var uint64Value uint64Value
180+ return & uint64SliceValueFast {
181+ uint64Slice : v ,
182+ uint64Value : & uint64Value ,
183+ value : & uint64Value ,
184+ }
185+ }
186+
187+ func (v * uint64SliceValueFast ) Kind () reflect.Kind {
188+ return reflect .Slice
159189}
160190
161- func (v uint64SliceValue ) Interface () interface {} {
191+ func (v * uint64SliceValueFast ) Len () int {
192+ return len (v .uint64Slice )
193+ }
194+
195+ func (v * uint64SliceValueFast ) Index (i int ) data.Value {
196+ v .uint64Value .value = v .uint64Slice [i ]
197+ // NB: This avoids the CPU cost of converting *uint64Value to data.Value.
162198 return v .value
163199}
200+
201+ func (v * uint64SliceValueFast ) Interface () interface {} {
202+ return v .uint64Slice
203+ }
0 commit comments