This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-go.git


The following commit(s) were added to refs/heads/main by this push:
     new fbb40237 perf(arrow/compute): avoid goroutines for serial take (#1226)
fbb40237 is described below

commit fbb40237981c9b30043456c120716f5e1a76756b
Author: Minh Vu <[email protected]>
AuthorDate: Mon Aug 31 20:20:55 2026 +0200

    perf(arrow/compute): avoid goroutines for serial take (#1226)
    
    ## What changed
    
    - Added direct serial execution for Take on record batches and tables
    when there is one column or NumParallel is 1 or less.
    - Added the same path for chunked index arrays when there is one index
    chunk or NumParallel is 1 or less.
    - Kept the existing errgroup path for actual parallel work.
    
    ## Why
    
    The old path created errgroup and goroutine setup even when the work was
    already serial. This adds overhead for small record batches, one-column
    tables, and chunked indices.
    
    ## Benchmarks
    
    Command:
    
    go test ./arrow/compute -run "^$" -bench
    
"^BenchmarkTake(RecordSingleColumn|RecordMultiColumnSerial|TableSingleColumn|ArraySingleIndexChunk|ArrayMultiChunkSerial)$"
    -benchmem -benchtime=300ms -count=3
    
    Apple M1 Pro, Go 1.26.3, darwin/arm64.
    
    | Benchmark | Before | After |
    | --- | ---: | ---: |
    | Record, one column | 45 allocs/op, 3403 B/op | 36 allocs/op, 2642 B/op
    |
    | Record, 16 columns, serial | 480 allocs/op, 41945 B/op | 441
    allocs/op, 39380 B/op |
    | Table, one column | 52 allocs/op, 3819 B/op | 43 allocs/op, 3042 B/op
    |
    | Array, one index chunk | 44 allocs/op, 3370 B/op | 35 allocs/op, 2578
    B/op |
    | Array, 8 index chunks, serial | 247 allocs/op, 17995 B/op | 224
    allocs/op, 16136 B/op |
    
    ## Tests
    
    - go test ./arrow/compute -count=1
    - go test -race ./arrow/compute -count=1
    - go test ./arrow/... -count=1
    - Full go test ./... -count=1 with the Parquet test data directory
---
 arrow/compute/selection.go                         | 155 +++++++++------
 .../selection_take_serial_benchmark_test.go        | 210 +++++++++++++++++++++
 arrow/compute/selection_take_serial_test.go        | 143 ++++++++++++++
 3 files changed, 453 insertions(+), 55 deletions(-)

diff --git a/arrow/compute/selection.go b/arrow/compute/selection.go
index ea69f575..6b748daa 100644
--- a/arrow/compute/selection.go
+++ b/arrow/compute/selection.go
@@ -114,6 +114,26 @@ given by "indices". Nulls in "indices" emit null in the 
output`,
                })
 )
 
+func takeTableColumn(ctx context.Context, opts FunctionOptions, tbl 
arrow.Table, indices Datum, cols []arrow.Column, i int) error {
+       inCol := tbl.Column(i)
+       result, err := CallFunction(ctx, "take", opts,
+               &ChunkedDatum{Value: inCol.Data()},
+               indices)
+       if err != nil {
+               return err
+       }
+       defer result.Release()
+       out := result.(ArrayLikeDatum)
+       chunks := out.Chunks()
+       if out.Kind() == KindArray {
+               defer chunks[0].Release()
+       }
+       chk := arrow.NewChunked(out.Type(), chunks)
+       defer chk.Release()
+       cols[i] = *arrow.NewColumn(inCol.Field(), chk)
+       return nil
+}
+
 func takeTableImpl(ctx context.Context, opts FunctionOptions, args ...Datum) 
(Datum, error) {
        tbl := args[0].(*TableDatum).Value
        ncols := int(tbl.NumCols())
@@ -124,39 +144,42 @@ func takeTableImpl(ctx context.Context, opts 
FunctionOptions, args ...Datum) (Da
                }
        }()
 
-       eg, cctx := errgroup.WithContext(ctx)
-       eg.SetLimit(GetExecCtx(ctx).NumParallel)
-       for i := 0; i < ncols; i++ {
-               i := i
-               eg.Go(func() error {
-                       inCol := tbl.Column(i)
-                       result, err := CallFunction(cctx, "take", opts,
-                               &ChunkedDatum{Value: inCol.Data()},
-                               args[1])
-                       if err != nil {
-                               return err
-                       }
-                       defer result.Release()
-                       out := result.(ArrayLikeDatum)
-                       chunks := out.Chunks()
-                       if out.Kind() == KindArray {
-                               defer chunks[0].Release()
+       numParallel := GetExecCtx(ctx).NumParallel
+       if ncols <= 1 || numParallel <= 1 {
+               for i := 0; i < ncols; i++ {
+                       if err := takeTableColumn(ctx, opts, tbl, args[1], 
cols, i); err != nil {
+                               return nil, err
                        }
-                       chk := arrow.NewChunked(out.Type(), chunks)
-                       defer chk.Release()
-                       cols[i] = *arrow.NewColumn(inCol.Field(), chk)
-                       return nil
-               })
-       }
+               }
+       } else {
+               eg, cctx := errgroup.WithContext(ctx)
+               eg.SetLimit(numParallel)
+               for i := 0; i < ncols; i++ {
+                       i := i
+                       eg.Go(func() error {
+                               return takeTableColumn(cctx, opts, tbl, 
args[1], cols, i)
+                       })
+               }
 
-       if err := eg.Wait(); err != nil {
-               return nil, err
+               if err := eg.Wait(); err != nil {
+                       return nil, err
+               }
        }
 
        final := array.NewTable(tbl.Schema(), cols, -1)
        return &TableDatum{Value: final}, nil
 }
 
+func takeRecordColumn(ctx context.Context, opts FunctionOptions, rb 
arrow.RecordBatch, indices Datum, cols []arrow.Array, i int) error {
+       out, err := CallFunction(ctx, "array_take", opts, &ArrayDatum{Value: 
rb.Column(i).Data()}, indices)
+       if err != nil {
+               return err
+       }
+       defer out.Release()
+       cols[i] = out.(*ArrayDatum).MakeArray()
+       return nil
+}
+
 func takeRecordImpl(ctx context.Context, opts FunctionOptions, args ...Datum) 
(Datum, error) {
        indices := args[1]
        if indices.Kind() == KindChunked {
@@ -169,7 +192,7 @@ func takeRecordImpl(ctx context.Context, opts 
FunctionOptions, args ...Datum) (D
        }
 
        rb := args[0].(*RecordDatum).Value
-       ncols := rb.NumCols()
+       ncols := int(rb.NumCols())
        nrows := args[1].(ArrayLikeDatum).Len()
        cols := make([]arrow.Array, ncols)
        defer func() {
@@ -180,29 +203,41 @@ func takeRecordImpl(ctx context.Context, opts 
FunctionOptions, args ...Datum) (D
                }
        }()
 
-       eg, cctx := errgroup.WithContext(ctx)
-       eg.SetLimit(GetExecCtx(ctx).NumParallel)
-       for i := range rb.Columns() {
-               i := i
-               eg.Go(func() error {
-                       out, err := CallFunction(cctx, "array_take", opts, 
&ArrayDatum{Value: rb.Column(i).Data()}, indices)
-                       if err != nil {
-                               return err
+       numParallel := GetExecCtx(ctx).NumParallel
+       if ncols <= 1 || numParallel <= 1 {
+               for i := 0; i < ncols; i++ {
+                       if err := takeRecordColumn(ctx, opts, rb, indices, 
cols, i); err != nil {
+                               return nil, err
                        }
-                       defer out.Release()
-                       cols[i] = out.(*ArrayDatum).MakeArray()
-                       return nil
-               })
-       }
+               }
+       } else {
+               eg, cctx := errgroup.WithContext(ctx)
+               eg.SetLimit(numParallel)
+               for i := 0; i < ncols; i++ {
+                       i := i
+                       eg.Go(func() error {
+                               return takeRecordColumn(cctx, opts, rb, 
indices, cols, i)
+                       })
+               }
 
-       if err := eg.Wait(); err != nil {
-               return nil, err
+               if err := eg.Wait(); err != nil {
+                       return nil, err
+               }
        }
 
        outRec := array.NewRecordBatch(rb.Schema(), cols, nrows)
        return &RecordDatum{Value: outRec}, nil
 }
 
+func takeArrayChunk(ctx context.Context, opts FunctionOptions, values Datum, 
chunk arrow.Array) (arrow.Array, error) {
+       result, err := CallFunction(ctx, "array_take", opts, values, 
&ArrayDatum{Value: chunk.Data()})
+       if err != nil {
+               return nil, err
+       }
+       defer result.Release()
+       return result.(*ArrayDatum).MakeArray(), nil
+}
+
 func takeArrayImpl(ctx context.Context, opts FunctionOptions, args ...Datum) 
(Datum, error) {
        switch args[1].Kind() {
        case KindArray:
@@ -218,22 +253,32 @@ func takeArrayImpl(ctx context.Context, opts 
FunctionOptions, args ...Datum) (Da
                        }
                }()
 
-               eg, cctx := errgroup.WithContext(ctx)
-               eg.SetLimit(GetExecCtx(ctx).NumParallel)
-               for i := range chunks {
-                       i := i
-                       eg.Go(func() error {
-                               result, err := CallFunction(cctx, "array_take", 
opts, args[0], &ArrayDatum{Value: chunks[i].Data()})
+               numParallel := GetExecCtx(ctx).NumParallel
+               if len(chunks) <= 1 || numParallel <= 1 {
+                       for i, chunk := range chunks {
+                               result, err := takeArrayChunk(ctx, opts, 
args[0], chunk)
                                if err != nil {
-                                       return err
+                                       return nil, err
                                }
-                               defer result.Release()
-                               out[i] = result.(*ArrayDatum).MakeArray()
-                               return nil
-                       })
-               }
-               if err := eg.Wait(); err != nil {
-                       return nil, err
+                               out[i] = result
+                       }
+               } else {
+                       eg, cctx := errgroup.WithContext(ctx)
+                       eg.SetLimit(numParallel)
+                       for i := range chunks {
+                               i := i
+                               eg.Go(func() error {
+                                       result, err := takeArrayChunk(cctx, 
opts, args[0], chunks[i])
+                                       if err != nil {
+                                               return err
+                                       }
+                                       out[i] = result
+                                       return nil
+                               })
+                       }
+                       if err := eg.Wait(); err != nil {
+                               return nil, err
+                       }
                }
                return &ChunkedDatum{
                        Value: arrow.NewChunked(args[0].(*ArrayDatum).Type(), 
out)}, nil
diff --git a/arrow/compute/selection_take_serial_benchmark_test.go 
b/arrow/compute/selection_take_serial_benchmark_test.go
new file mode 100644
index 00000000..3edec311
--- /dev/null
+++ b/arrow/compute/selection_take_serial_benchmark_test.go
@@ -0,0 +1,210 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.24
+
+package compute_test
+
+import (
+       "context"
+       "fmt"
+       "testing"
+
+       "github.com/apache/arrow-go/v18/arrow"
+       "github.com/apache/arrow-go/v18/arrow/array"
+       "github.com/apache/arrow-go/v18/arrow/compute"
+       "github.com/apache/arrow-go/v18/arrow/memory"
+)
+
+func newTakeInt32Array(mem memory.Allocator, n int) arrow.Array {
+       values := make([]int32, n)
+       for i := range values {
+               values[i] = int32(i)
+       }
+       bldr := array.NewInt32Builder(mem)
+       bldr.AppendValues(values, nil)
+       result := bldr.NewInt32Array()
+       bldr.Release()
+       return result
+}
+
+func newTakeIndices(mem memory.Allocator, n int) arrow.Array {
+       values := make([]int32, n)
+       for i := range values {
+               values[i] = int32(n - i - 1)
+       }
+       bldr := array.NewInt32Builder(mem)
+       bldr.AppendValues(values, nil)
+       result := bldr.NewInt32Array()
+       bldr.Release()
+       return result
+}
+
+func BenchmarkTakeRecordSingleColumn(b *testing.B) {
+       const (
+               nrows   = 256
+               nselect = 128
+       )
+
+       mem := memory.NewGoAllocator()
+       ctx := compute.WithAllocator(context.Background(), mem)
+       field := arrow.Field{Name: "value", Type: arrow.PrimitiveTypes.Int32}
+       schema := arrow.NewSchema([]arrow.Field{field}, nil)
+       values := newTakeInt32Array(mem, nrows)
+       defer values.Release()
+       indices := newTakeIndices(mem, nselect)
+       defer indices.Release()
+       batch := array.NewRecordBatch(schema, []arrow.Array{values}, nrows)
+       defer batch.Release()
+
+       b.ReportAllocs()
+       b.ResetTimer()
+       for b.Loop() {
+               result, err := compute.Take(ctx, *compute.DefaultTakeOptions(),
+                       &compute.RecordDatum{Value: batch}, 
&compute.ArrayDatum{Value: indices.Data()})
+               if err != nil {
+                       b.Fatal(err)
+               }
+               result.Release()
+       }
+}
+
+func BenchmarkTakeRecordMultiColumnSerial(b *testing.B) {
+       const (
+               nrows   = 256
+               ncols   = 16
+               nselect = 128
+       )
+
+       mem := memory.NewGoAllocator()
+       ctx := serialTakeContext(mem, 1)
+       fields := make([]arrow.Field, ncols)
+       values := make([]arrow.Array, ncols)
+       for i := range fields {
+               fields[i] = arrow.Field{Name: fmt.Sprintf("value_%d", i), Type: 
arrow.PrimitiveTypes.Int32}
+               values[i] = newTakeInt32Array(mem, nrows)
+       }
+       schema := arrow.NewSchema(fields, nil)
+       batch := array.NewRecordBatch(schema, values, nrows)
+       for _, value := range values {
+               value.Release()
+       }
+       defer batch.Release()
+       indices := newTakeIndices(mem, nselect)
+       defer indices.Release()
+
+       b.ReportAllocs()
+       b.ResetTimer()
+       for b.Loop() {
+               result, err := compute.Take(ctx, *compute.DefaultTakeOptions(),
+                       &compute.RecordDatum{Value: batch}, 
&compute.ArrayDatum{Value: indices.Data()})
+               if err != nil {
+                       b.Fatal(err)
+               }
+               result.Release()
+       }
+}
+
+func BenchmarkTakeTableSingleColumn(b *testing.B) {
+       const (
+               nrows   = 256
+               nselect = 128
+       )
+
+       mem := memory.NewGoAllocator()
+       ctx := compute.WithAllocator(context.Background(), mem)
+       field := arrow.Field{Name: "value", Type: arrow.PrimitiveTypes.Int32}
+       schema := arrow.NewSchema([]arrow.Field{field}, nil)
+       values := newTakeInt32Array(mem, nrows)
+       defer values.Release()
+       column := arrow.NewColumnFromArr(field, values)
+       table := array.NewTable(schema, []arrow.Column{column}, nrows)
+       column.Release()
+       defer table.Release()
+       indices := newTakeIndices(mem, nselect)
+       defer indices.Release()
+
+       b.ReportAllocs()
+       b.ResetTimer()
+       for b.Loop() {
+               result, err := compute.Take(ctx, *compute.DefaultTakeOptions(),
+                       &compute.TableDatum{Value: table}, 
&compute.ArrayDatum{Value: indices.Data()})
+               if err != nil {
+                       b.Fatal(err)
+               }
+               result.Release()
+       }
+}
+
+func BenchmarkTakeArraySingleIndexChunk(b *testing.B) {
+       const (
+               nrows   = 256
+               nselect = 128
+       )
+
+       mem := memory.NewGoAllocator()
+       ctx := compute.WithAllocator(context.Background(), mem)
+       values := newTakeInt32Array(mem, nrows)
+       defer values.Release()
+       indices := newTakeIndices(mem, nselect)
+       defer indices.Release()
+       chunkedIndices := arrow.NewChunked(indices.DataType(), 
[]arrow.Array{indices})
+       defer chunkedIndices.Release()
+
+       b.ReportAllocs()
+       b.ResetTimer()
+       for b.Loop() {
+               result, err := compute.Take(ctx, *compute.DefaultTakeOptions(),
+                       &compute.ArrayDatum{Value: values.Data()}, 
&compute.ChunkedDatum{Value: chunkedIndices})
+               if err != nil {
+                       b.Fatal(err)
+               }
+               result.Release()
+       }
+}
+
+func BenchmarkTakeArrayMultiChunkSerial(b *testing.B) {
+       const (
+               nrows        = 256
+               chunksCount  = 8
+               rowsPerChunk = 16
+       )
+
+       mem := memory.NewGoAllocator()
+       ctx := serialTakeContext(mem, 1)
+       values := newTakeInt32Array(mem, nrows)
+       defer values.Release()
+       chunks := make([]arrow.Array, chunksCount)
+       for i := range chunks {
+               chunks[i] = newTakeIndices(mem, rowsPerChunk)
+       }
+       chunkedIndices := arrow.NewChunked(arrow.PrimitiveTypes.Int32, chunks)
+       for _, chunk := range chunks {
+               chunk.Release()
+       }
+       defer chunkedIndices.Release()
+
+       b.ReportAllocs()
+       b.ResetTimer()
+       for b.Loop() {
+               result, err := compute.Take(ctx, *compute.DefaultTakeOptions(),
+                       &compute.ArrayDatum{Value: values.Data()}, 
&compute.ChunkedDatum{Value: chunkedIndices})
+               if err != nil {
+                       b.Fatal(err)
+               }
+               result.Release()
+       }
+}
diff --git a/arrow/compute/selection_take_serial_test.go 
b/arrow/compute/selection_take_serial_test.go
new file mode 100644
index 00000000..9f57c149
--- /dev/null
+++ b/arrow/compute/selection_take_serial_test.go
@@ -0,0 +1,143 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//go:build go1.18
+
+package compute_test
+
+import (
+       "context"
+       "fmt"
+       "strings"
+       "testing"
+
+       "github.com/apache/arrow-go/v18/arrow"
+       "github.com/apache/arrow-go/v18/arrow/array"
+       "github.com/apache/arrow-go/v18/arrow/compute"
+       "github.com/apache/arrow-go/v18/arrow/memory"
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+)
+
+func serialTakeContext(mem memory.Allocator, numParallel int) context.Context {
+       execCtx := compute.DefaultExecCtx()
+       execCtx.NumParallel = numParallel
+       return compute.SetExecCtx(compute.WithAllocator(context.Background(), 
mem), execCtx)
+}
+
+func TestTakeRecordBatchSerialExecution(t *testing.T) {
+       mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
+       defer mem.AssertSize(t, 0)
+
+       schema := arrow.NewSchema([]arrow.Field{
+               {Name: "a", Type: arrow.PrimitiveTypes.Int32, Nullable: true},
+               {Name: "b", Type: arrow.BinaryTypes.String, Nullable: true},
+       }, nil)
+       values, _, err := array.RecordFromJSON(mem, schema, strings.NewReader(`[
+               {"a": 0, "b": "zero"},
+               {"a": 1, "b": "one"},
+               {"a": null, "b": "null"},
+               {"a": 3, "b": "three"}
+       ]`))
+       require.NoError(t, err)
+       defer values.Release()
+       indices, _, err := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, 
strings.NewReader(`[3, 1, null, 0]`))
+       require.NoError(t, err)
+       defer indices.Release()
+       expected, _, err := array.RecordFromJSON(mem, schema, 
strings.NewReader(`[
+               {"a": 3, "b": "three"},
+               {"a": 1, "b": "one"},
+               {"a": null, "b": null},
+               {"a": 0, "b": "zero"}
+       ]`))
+       require.NoError(t, err)
+       defer expected.Release()
+
+       for _, numParallel := range []int{1, 0, -1} {
+               numParallel := numParallel
+               t.Run(fmt.Sprintf("parallelism-%d", numParallel), func(t 
*testing.T) {
+                       result, err := compute.Take(serialTakeContext(mem, 
numParallel), *compute.DefaultTakeOptions(),
+                               &compute.RecordDatum{Value: values}, 
&compute.ArrayDatum{Value: indices.Data()})
+                       require.NoError(t, err)
+                       defer result.Release()
+
+                       assert.True(t, array.RecordEqual(expected, 
result.(*compute.RecordDatum).Value))
+               })
+       }
+}
+
+func TestTakeTableSerialExecution(t *testing.T) {
+       mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
+       defer mem.AssertSize(t, 0)
+
+       schema := arrow.NewSchema([]arrow.Field{
+               {Name: "a", Type: arrow.PrimitiveTypes.Int32, Nullable: true},
+               {Name: "b", Type: arrow.BinaryTypes.String, Nullable: true},
+       }, nil)
+       values, err := array.TableFromJSON(mem, schema, []string{
+               `[{"a": 0, "b": "zero"}, {"a": 1, "b": "one"}]`,
+               `[{"a": 2, "b": "two"}, {"a": 3, "b": "three"}]`,
+       })
+       require.NoError(t, err)
+       defer values.Release()
+       indices, _, err := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, 
strings.NewReader(`[3, 1, 0]`))
+       require.NoError(t, err)
+       defer indices.Release()
+       expected, err := array.TableFromJSON(mem, schema, []string{
+               `[{"a": 3, "b": "three"}, {"a": 1, "b": "one"}, {"a": 0, "b": 
"zero"}]`,
+       })
+       require.NoError(t, err)
+       defer expected.Release()
+
+       for _, numParallel := range []int{1, 0, -1} {
+               numParallel := numParallel
+               t.Run(fmt.Sprintf("parallelism-%d", numParallel), func(t 
*testing.T) {
+                       result, err := compute.Take(serialTakeContext(mem, 
numParallel), *compute.DefaultTakeOptions(),
+                               &compute.TableDatum{Value: values}, 
&compute.ArrayDatum{Value: indices.Data()})
+                       require.NoError(t, err)
+                       defer result.Release()
+
+                       assert.True(t, array.TableEqual(expected, 
result.(*compute.TableDatum).Value))
+               })
+       }
+}
+
+func TestTakeArraySerialExecution(t *testing.T) {
+       mem := memory.NewCheckedAllocator(memory.DefaultAllocator)
+       defer mem.AssertSize(t, 0)
+
+       values, _, err := array.FromJSON(mem, arrow.PrimitiveTypes.Int32, 
strings.NewReader(`[10, 20, 30, 40]`))
+       require.NoError(t, err)
+       defer values.Release()
+       indices, err := array.ChunkedFromJSON(mem, arrow.PrimitiveTypes.Int32, 
[]string{`[3, 1]`, `[null, 0]`})
+       require.NoError(t, err)
+       defer indices.Release()
+       expected, err := array.ChunkedFromJSON(mem, arrow.PrimitiveTypes.Int32, 
[]string{`[40, 20]`, `[null, 10]`})
+       require.NoError(t, err)
+       defer expected.Release()
+
+       for _, numParallel := range []int{1, 0, -1} {
+               numParallel := numParallel
+               t.Run(fmt.Sprintf("parallelism-%d", numParallel), func(t 
*testing.T) {
+                       result, err := compute.Take(serialTakeContext(mem, 
numParallel), *compute.DefaultTakeOptions(),
+                               &compute.ArrayDatum{Value: values.Data()}, 
&compute.ChunkedDatum{Value: indices})
+                       require.NoError(t, err)
+                       defer result.Release()
+
+                       assert.True(t, array.ChunkedEqual(expected, 
result.(*compute.ChunkedDatum).Value))
+               })
+       }
+}

Reply via email to