This is an automated email from the ASF dual-hosted git repository.
laskoviymishka pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-go.git
The following commit(s) were added to refs/heads/main by this push:
new fa4610eba perf(substrait): avoid repeated literal formatting (#2135)
fa4610eba is described below
commit fa4610ebace2588dde43b8f6f193fa6882138b25
Author: Minh Vu <[email protected]>
AuthorDate: Wed Oct 7 13:53:07 2026 +0200
perf(substrait): avoid repeated literal formatting (#2135)
Signed-off-by: Minh Vu <[email protected]>
---
table/substrait/substrait.go | 29 +++++++++++---
table/substrait/substrait_bench_test.go | 70 +++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/table/substrait/substrait.go b/table/substrait/substrait.go
index e09fc4629..bcb670bb9 100644
--- a/table/substrait/substrait.go
+++ b/table/substrait/substrait.go
@@ -351,13 +351,32 @@ func toSubstraitLiteralSet(typ iceberg.Type, lits
[]iceberg.Literal) expr.ListLi
return nil
}
- sort.Slice(lits, func(i, j int) bool {
- return lits[i].String() < lits[j].String()
- })
+ switch typ.(type) {
+ case iceberg.BooleanType, iceberg.StringType:
+ sort.Slice(lits, func(i, j int) bool {
+ return lits[i].String() < lits[j].String()
+ })
+ default:
+ type keyedLiteral struct {
+ literal iceberg.Literal
+ key string
+ }
+
+ keyed := make([]keyedLiteral, len(lits))
+ for i, lit := range lits {
+ keyed[i] = keyedLiteral{literal: lit, key: lit.String()}
+ }
+ sort.Slice(keyed, func(i, j int) bool {
+ return keyed[i].key < keyed[j].key
+ })
+ for i, item := range keyed {
+ lits[i] = item.literal
+ }
+ }
out := make([]expr.Literal, len(lits))
- for i, l := range lits {
- out[i] = toSubstraitLiteral(typ, l)
+ for i, lit := range lits {
+ out[i] = toSubstraitLiteral(typ, lit)
}
return out
diff --git a/table/substrait/substrait_bench_test.go
b/table/substrait/substrait_bench_test.go
new file mode 100644
index 000000000..2d3c70cd4
--- /dev/null
+++ b/table/substrait/substrait_bench_test.go
@@ -0,0 +1,70 @@
+// 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.
+
+package substrait
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/apache/iceberg-go"
+)
+
+var benchmarkSubstraitLiteralSetResult any
+
+func BenchmarkToSubstraitLiteralSet(b *testing.B) {
+ cases := []struct {
+ name string
+ typ iceberg.Type
+ lit func(int) iceberg.Literal
+ }{
+ {
+ name: "int64",
+ typ: iceberg.PrimitiveTypes.Int64,
+ lit: func(value int) iceberg.Literal {
+ return iceberg.Int64Literal(1_000_000 + value)
+ },
+ },
+ {
+ name: "string",
+ typ: iceberg.PrimitiveTypes.String,
+ lit: func(value int) iceberg.Literal {
+ return
iceberg.StringLiteral(fmt.Sprintf("value-%08d", value))
+ },
+ },
+ }
+
+ for _, testCase := range cases {
+ b.Run(testCase.name, func(b *testing.B) {
+ for _, size := range []int{10, 100, 1000} {
+ template := make([]iceberg.Literal, size)
+ for i := range template {
+ template[i] = testCase.lit((i * 7919) %
size)
+ }
+ lits := make([]iceberg.Literal, size)
+
+ b.Run(fmt.Sprintf("size=%d", size), func(b
*testing.B) {
+ b.ReportAllocs()
+ for range b.N {
+ copy(lits, template)
+
benchmarkSubstraitLiteralSetResult = toSubstraitLiteralSet(testCase.typ, lits)
+ }
+ })
+ }
+ })
+ }
+}