Skip to content

Commit e20deef

Browse files
author
Amit Kumar
committed
removed creation of map in a loop
Signed-off-by: Amit Kumar <[email protected]>
1 parent 7ab9134 commit e20deef

File tree

5 files changed

+103
-43
lines changed

5 files changed

+103
-43
lines changed

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ require (
6868
github.com/bytedance/sonic v1.13.2
6969
github.com/cenkalti/backoff/v4 v4.2.1
7070
github.com/cockroachdb/redact v1.1.3
71+
github.com/expr-lang/expr v1.17.6
7172
github.com/google/uuid v1.6.0
7273
github.com/greatroar/blobloom v0.0.0-00010101000000-000000000000
7374
github.com/hashicorp/golang-lru/v2 v2.0.7
@@ -157,7 +158,6 @@ require (
157158
github.com/ebitengine/purego v0.8.1 // indirect
158159
github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect
159160
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
160-
github.com/expr-lang/expr v1.15.7 // indirect
161161
github.com/felixge/httpsnoop v1.0.4 // indirect
162162
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
163163
github.com/fsnotify/fsnotify v1.8.0 // indirect
@@ -308,7 +308,6 @@ require (
308308
replace (
309309
github.com/apache/arrow/go/v17 => github.com/milvus-io/arrow/go/v17 v17.0.0
310310
github.com/bketelsen/crypt => github.com/bketelsen/crypt v0.0.4 // Fix security alert for core-os/etcd
311-
github.com/expr-lang/expr => github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9
312311
github.com/go-kit/kit => github.com/go-kit/kit v0.1.0
313312
github.com/golang-jwt/jwt => github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
314313
github.com/greatroar/blobloom => github.com/milvus-io/blobloom v0.0.0-20240603110411-471ae49f3b93

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,6 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
111111
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
112112
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
113113
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
114-
github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9 h1:eXnmJhsHt8m6NU3IJ19UthXJ8JK6e3tmfN07nym3BXs=
115-
github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
116114
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
117115
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
118116
github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu1fXES56uXniYFv4yDA=
@@ -205,11 +203,11 @@ github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl
205203
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
206204
github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8=
207205
github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY=
208-
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
209-
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
206+
github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ=
207+
github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA=
210208
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
211-
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
212-
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
209+
github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA=
210+
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
213211
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
214212
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
215213
github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
@@ -341,6 +339,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
341339
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
342340
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
343341
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
342+
github.com/expr-lang/expr v1.17.6 h1:1h6i8ONk9cexhDmowO/A64VPxHScu7qfSl2k8OlINec=
343+
github.com/expr-lang/expr v1.17.6/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
344344
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
345345
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
346346
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=

internal/util/function/rerank/expr_rerank.go

Lines changed: 94 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,9 @@
1-
/*
2-
* # Licensed to the LF AI & Data foundation under one
3-
* # or more contributor license agreements. See the NOTICE file
4-
* # distributed with this work for additional information
5-
* # regarding copyright ownership. The ASF licenses this file
6-
* # to you under the Apache License, Version 2.0 (the
7-
* # "License"); you may not use this file except in compliance
8-
* # with the License. You may obtain a copy of the License at
9-
* #
10-
* # http://www.apache.org/licenses/LICENSE-2.0
11-
* #
12-
* # Unless required by applicable law or agreed to in writing, software
13-
* # distributed under the License is distributed on an "AS IS" BASIS,
14-
* # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15-
* # See the License for the specific language governing permissions and
16-
* # limitations under the License.
17-
*/
18-
191
package rerank
202

213
import (
224
"context"
235
"fmt"
6+
"math"
247
"strings"
258

269
"github.com/expr-lang/expr"
@@ -44,6 +27,70 @@ const (
4427
ExprNormalizeKey = "normalize"
4528
)
4629

30+
// toFloat64 converts various numeric types to float64
31+
func toFloat64(v interface{}) float64 {
32+
switch val := v.(type) {
33+
case float64:
34+
return val
35+
case float32:
36+
return float64(val)
37+
case int:
38+
return float64(val)
39+
case int32:
40+
return float64(val)
41+
case int64:
42+
return float64(val)
43+
default:
44+
return 0.0 // fallback for unsupported types
45+
}
46+
}
47+
48+
// mathFunctions contains all mathematical functions for expr-lang
49+
// Created once at package level to avoid recreating functions on every call
50+
var mathFunctions = map[string]interface{}{
51+
// Basic math functions with type conversion
52+
"abs": func(x interface{}) float64 { return math.Abs(toFloat64(x)) },
53+
"ceil": func(x interface{}) float64 { return math.Ceil(toFloat64(x)) },
54+
"floor": func(x interface{}) float64 { return math.Floor(toFloat64(x)) },
55+
"round": func(x interface{}) float64 { return math.Round(toFloat64(x)) },
56+
"sqrt": func(x interface{}) float64 { return math.Sqrt(toFloat64(x)) },
57+
"pow": func(x, y interface{}) float64 { return math.Pow(toFloat64(x), toFloat64(y)) },
58+
59+
// Exponential and logarithmic functions with type conversion
60+
"exp": func(x interface{}) float64 { return math.Exp(toFloat64(x)) },
61+
"exp2": func(x interface{}) float64 { return math.Exp2(toFloat64(x)) },
62+
"log": func(x interface{}) float64 { return math.Log(toFloat64(x)) },
63+
"log10": func(x interface{}) float64 { return math.Log10(toFloat64(x)) },
64+
"log2": func(x interface{}) float64 { return math.Log2(toFloat64(x)) },
65+
66+
// Min/Max functions with type conversion
67+
"min": func(x, y interface{}) float64 { return math.Min(toFloat64(x), toFloat64(y)) },
68+
"max": func(x, y interface{}) float64 { return math.Max(toFloat64(x), toFloat64(y)) },
69+
70+
// Utility functions with type conversion
71+
"mod": func(x, y interface{}) float64 { return math.Mod(toFloat64(x), toFloat64(y)) },
72+
"remainder": func(x, y interface{}) float64 { return math.Remainder(toFloat64(x), toFloat64(y)) },
73+
"trunc": func(x interface{}) float64 { return math.Trunc(toFloat64(x)) },
74+
75+
// Clamping function with type conversion
76+
"clamp": func(x, min_val, max_val interface{}) float64 {
77+
xf := toFloat64(x)
78+
minf := toFloat64(min_val)
79+
maxf := toFloat64(max_val)
80+
if xf < minf {
81+
return minf
82+
}
83+
if xf > maxf {
84+
return maxf
85+
}
86+
return xf
87+
},
88+
89+
// Mathematical constants
90+
"PI": math.Pi,
91+
"E": math.E,
92+
}
93+
4794
func newExprRerank(collSchema *schemapb.CollectionSchema, funcSchema *schemapb.FunctionSchema) (Reranker, error) {
4895
base, err := newRerankBase(collSchema, funcSchema, ExprRerankName, false)
4996
if err != nil {
@@ -70,12 +117,21 @@ func newExprRerank(collSchema *schemapb.CollectionSchema, funcSchema *schemapb.F
70117
return nil, fmt.Errorf("expr rerank requires %s parameter", ExprCodeKey)
71118
}
72119

120+
// Create environment with mathematical functions
121+
// Pre-size map to avoid growth during insertion: 3 core variables + len(mathFunctions)
122+
env := make(map[string]interface{}, 3+len(mathFunctions))
123+
124+
env["score"] = float32(0)
125+
env["rank"] = int(0)
126+
env["fields"] = map[string]interface{}{}
127+
128+
// Add mathematical functions to the environment (just copying references)
129+
for name, fn := range mathFunctions {
130+
env[name] = fn
131+
}
132+
73133
// Compile the expression
74-
program, err := expr.Compile(exprCode, expr.Env(map[string]interface{}{
75-
"score": float32(0),
76-
"rank": int(0),
77-
"fields": map[string]interface{}{},
78-
}))
134+
program, err := expr.Compile(exprCode, expr.Env(env))
79135
if err != nil {
80136
return nil, fmt.Errorf("failed to compile expression: %w", err)
81137
}
@@ -95,7 +151,6 @@ func newExprRerank(collSchema *schemapb.CollectionSchema, funcSchema *schemapb.F
95151
needNormalize: needNormalize,
96152
}, nil
97153
}
98-
99154
func (e *ExprRerank[T]) processOneSearchData(ctx context.Context, searchParams *SearchParams, cols []*columns, idGroup map[any]any) (*IDScores[T], error) {
100155
newScores := map[T]float32{}
101156
idLocations := make(map[T]IDLoc)
@@ -113,14 +168,21 @@ func (e *ExprRerank[T]) processOneSearchData(ctx context.Context, searchParams *
113168
continue // Already processed (use first occurrence)
114169
}
115170

116-
// Prepare environment for expression evaluation
117-
env := map[string]interface{}{
118-
"score": scores[idx],
119-
"rank": idx,
171+
// Prepare environment with dynamic values and math functions
172+
// Pre-size map to avoid growth during insertion: 3 core variables + len(mathFunctions)
173+
env := make(map[string]interface{}, 3+len(mathFunctions))
174+
175+
env["score"] = scores[idx]
176+
env["rank"] = idx
177+
178+
// Add mathematical functions to the runtime environment (just copying references)
179+
for name, fn := range mathFunctions {
180+
env[name] = fn
120181
}
121182

122183
// Add field values to environment
123-
fields := make(map[string]interface{})
184+
// Pre-size fields map for typical field count
185+
fields := make(map[string]interface{}, len(e.inputFieldNames))
124186
for fieldIdx, fieldName := range e.inputFieldNames {
125187
if fieldIdx < len(col.data) {
126188
switch data := col.data[fieldIdx].(type) {
@@ -159,13 +221,13 @@ func (e *ExprRerank[T]) processOneSearchData(ctx context.Context, searchParams *
159221
return nil, fmt.Errorf("failed to execute expression for id %v: %w", id, err)
160222
}
161223

162-
// Convert output to float32
224+
// Convert output to float32 (fast path for common types)
163225
var newScore float32
164226
switch v := output.(type) {
165-
case float32:
166-
newScore = v
167227
case float64:
168228
newScore = float32(v)
229+
case float32:
230+
newScore = v
169231
case int:
170232
newScore = float32(v)
171233
case int64:

pkg/go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ require (
227227

228228
replace (
229229
github.com/bketelsen/crypt => github.com/bketelsen/crypt v0.0.4 // Fix security alert for core-os/etcd
230-
github.com/expr-lang/expr => github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9
231230
github.com/go-kit/kit => github.com/go-kit/kit v0.1.0
232231
github.com/golang-jwt/jwt => github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
233232
github.com/ianlancetaylor/cgosymbolizer => github.com/milvus-io/cgosymbolizer v0.0.0-20250318084424-114f4050c3a6

pkg/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,6 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
103103
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
104104
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
105105
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
106-
github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9 h1:eXnmJhsHt8m6NU3IJ19UthXJ8JK6e3tmfN07nym3BXs=
107-
github.com/SimFG/expr v0.0.0-20250513112851-9b981e8400b9/go.mod h1:8/vRC7+7HBzESEqt5kKpYXxrxkr31SaO8r40VO/1IT4=
108106
github.com/actgardner/gogen-avro/v10 v10.1.0/go.mod h1:o+ybmVjEa27AAr35FRqU98DJu1fXES56uXniYFv4yDA=
109107
github.com/actgardner/gogen-avro/v10 v10.2.1/go.mod h1:QUhjeHPchheYmMDni/Nx7VB0RsT/ee8YIgGY/xpEQgQ=
110108
github.com/actgardner/gogen-avro/v9 v9.1.0/go.mod h1:nyTj6wPqDJoxM3qdnjcLv+EnMDSDFqE0qDpva2QRmKc=
@@ -263,6 +261,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
263261
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
264262
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
265263
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
264+
github.com/expr-lang/expr v1.15.7 h1:BK0JcWUkoW6nrbLBo6xCKhz4BvH5DSOOu1Gx5lucyZo=
265+
github.com/expr-lang/expr v1.15.7/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ=
266266
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=
267267
github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
268268
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=

0 commit comments

Comments
 (0)