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)
+                                       }
+                               })
+                       }
+               })
+       }
+}

Reply via email to