Skip to content

Commit

Permalink
Micro optimizations to type-testing utility functions. (#518)
Browse files Browse the repository at this point in the history
* Fix benchmark tests
* Minor changes to type-testing utilities to improve performance
  • Loading branch information
TristonianJones committed Mar 22, 2022
1 parent ffa9b84 commit 0e2dde4
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 20 deletions.
1 change: 1 addition & 0 deletions common/types/BUILD.bazel
Expand Up @@ -73,6 +73,7 @@ go_test(
"timestamp_test.go",
"type_test.go",
"uint_test.go",
"util_test.go",
],
embed = [":go_default_library"],
deps = [
Expand Down
13 changes: 6 additions & 7 deletions common/types/bool.go
Expand Up @@ -130,12 +130,11 @@ func (b Bool) Value() interface{} {
}

// IsBool returns whether the input ref.Val or ref.Type is equal to BoolType.
func IsBool(elem interface{}) bool {
switch elem := elem.(type) {
case ref.Type:
return elem == BoolType
case ref.Val:
return IsBool(elem.Type())
func IsBool(elem ref.Val) bool {
switch elem.(type) {
case Bool:
return true
default:
return false
}
return false
}
8 changes: 8 additions & 0 deletions common/types/bool_test.go
Expand Up @@ -150,3 +150,11 @@ func TestIsBool(t *testing.T) {
t.Error("Non-boolean value tested as boolean.")
}
}

func BenchmarkIsBool(b *testing.B) {
for i := 0; i < b.N; i++ {
if !(IsBool(True) && !IsBool(IntNegOne)) {
b.Fatal("IsBool() failed to return proper result")
}
}
}
6 changes: 4 additions & 2 deletions common/types/compare.go
Expand Up @@ -16,6 +16,8 @@ package types

import (
"math"

"github.com/google/cel-go/common/types/ref"
)

func compareDoubleInt(d Double, i Int) Int {
Expand Down Expand Up @@ -74,7 +76,7 @@ func compareDouble(a, b Double) Int {
return IntZero
}

func compareInt(a, b Int) Int {
func compareInt(a, b Int) ref.Val {
if a < b {
return IntNegOne
}
Expand All @@ -84,7 +86,7 @@ func compareInt(a, b Int) Int {
return IntZero
}

func compareUint(a, b Uint) Int {
func compareUint(a, b Uint) ref.Val {
if a < b {
return IntNegOne
}
Expand Down
13 changes: 8 additions & 5 deletions common/types/err.go
Expand Up @@ -78,12 +78,10 @@ func ValOrErr(val ref.Val, format string, args ...interface{}) ref.Val {
if val == nil {
return NewErr(format, args...)
}
switch val.Type() {
case ErrType, UnknownType:
if IsUnknownOrError(val) {
return val
default:
return NewErr(format, args...)
}
return NewErr(format, args...)
}

// wrapErr wraps an existing Go error value into a CEL Err value.
Expand Down Expand Up @@ -126,5 +124,10 @@ func (e *Err) Value() interface{} {
// IsError returns whether the input element ref.Type or ref.Val is equal to
// the ErrType singleton.
func IsError(val ref.Val) bool {
return val.Type() == ErrType
switch val.(type) {
case *Err:
return true
default:
return false
}
}
11 changes: 8 additions & 3 deletions common/types/unknown.go
Expand Up @@ -34,12 +34,12 @@ func (u Unknown) ConvertToNative(typeDesc reflect.Type) (interface{}, error) {
return u.Value(), nil
}

// ConvertToType implements ref.Val.ConvertToType.
// ConvertToType is an identity function since unknown values cannot be modified.
func (u Unknown) ConvertToType(typeVal ref.Type) ref.Val {
return u
}

// Equal implements ref.Val.Equal.
// Equal is an identity function since unknown values cannot be modified.
func (u Unknown) Equal(other ref.Val) ref.Val {
return u
}
Expand All @@ -57,5 +57,10 @@ func (u Unknown) Value() interface{} {
// IsUnknown returns whether the element ref.Type or ref.Val is equal to the
// UnknownType singleton.
func IsUnknown(val ref.Val) bool {
return val.Type() == UnknownType
switch val.(type) {
case Unknown:
return true
default:
return false
}
}
4 changes: 2 additions & 2 deletions common/types/util.go
Expand Up @@ -20,8 +20,8 @@ import (

// IsUnknownOrError returns whether the input element ref.Val is an ErrType or UnknownType.
func IsUnknownOrError(val ref.Val) bool {
switch val.Type() {
case UnknownType, ErrType:
switch val.(type) {
case Unknown, *Err:
return true
}
return false
Expand Down
27 changes: 27 additions & 0 deletions common/types/util_test.go
@@ -0,0 +1,27 @@
// Copyright 2022 Google LLC
//
// Licensed 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 types

import "testing"

func BenchmarkIsUnknownOrError(b *testing.B) {
err := NewErr("test")
unk := Unknown{}
for i := 0; i < b.N; i++ {
if !(IsUnknownOrError(unk) && IsUnknownOrError(err) && !IsUnknownOrError(IntOne)) {
b.Fatal("IsUnknownOrError() provided an incorrect result.")
}
}
}
8 changes: 7 additions & 1 deletion interpreter/interpreter_test.go
Expand Up @@ -876,7 +876,7 @@ var (
},
},
{
name: "matches error",
name: "matches_error",
expr: `input.matches(')k.*')`,
env: []*exprpb.Decl{
decls.NewVar("input", decls.String),
Expand Down Expand Up @@ -1343,6 +1343,9 @@ var (

func BenchmarkInterpreter(b *testing.B) {
for _, tst := range testData {
if tst.err != "" || tst.progErr != "" {
continue
}
prg, vars, err := program(b, &tst, Optimize(), CompileRegexConstants(MatchesRegexOptimization))
if err != nil {
b.Fatal(err)
Expand All @@ -1361,6 +1364,9 @@ func BenchmarkInterpreter(b *testing.B) {
func BenchmarkInterpreter_Parallel(b *testing.B) {
for _, tst := range testData {
prg, vars, err := program(b, &tst, Optimize(), CompileRegexConstants(MatchesRegexOptimization))
if tst.err != "" || tst.progErr != "" {
continue
}
if err != nil {
b.Fatal(err)
}
Expand Down

0 comments on commit 0e2dde4

Please sign in to comment.