Skip to content

Commit

Permalink
Make GnoAttribute an int derived enum
Browse files Browse the repository at this point in the history
This change reduces on the key comparison
time (from hashing).
  • Loading branch information
odeke-em committed Jan 27, 2025
1 parent 9adc15d commit b8646c9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 31 deletions.
63 changes: 44 additions & 19 deletions gnovm/pkg/gnolang/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,26 +145,58 @@ func (loc Location) IsZero() bool {
// even after preprocessing. Temporary attributes (e.g. those
// for preprocessing) are stored in .data.

type GnoAttribute string
type GnoAttribute int

const (
ATTR_PREPROCESSED GnoAttribute = "ATTR_PREPROCESSED"
ATTR_PREDEFINED GnoAttribute = "ATTR_PREDEFINED"
ATTR_TYPE_VALUE GnoAttribute = "ATTR_TYPE_VALUE"
ATTR_TYPEOF_VALUE GnoAttribute = "ATTR_TYPEOF_VALUE"
ATTR_IOTA GnoAttribute = "ATTR_IOTA"
ATTR_LOOP_DEFINES GnoAttribute = "ATTR_LOOP_DEFINES" // []Name defined within loops.
ATTR_LOOP_USES GnoAttribute = "ATTR_LOOP_USES" // []Name loop defines actually used.
ATTR_SHIFT_RHS GnoAttribute = "ATTR_SHIFT_RHS"
ATTR_LAST_BLOCK_STMT GnoAttribute = "ATTR_LAST_BLOCK_STMT"
ATTR_GLOBAL GnoAttribute = "ATTR_GLOBAL"
ATTR_PREPROCESSED GnoAttribute = iota
ATTR_PREDEFINED
ATTR_TYPE_VALUE
ATTR_TYPEOF_VALUE
ATTR_IOTA
ATTR_LOOP_DEFINES
ATTR_LOOP_USES
ATTR_SHIFT_RHS
ATTR_LAST_BLOCK_STMT
ATTR_GLOBAL
)

func (ga GnoAttribute) String() string {
switch ga {
case ATTR_PREPROCESSED:
return "ATTR_PREPROCESSED"
case ATTR_PREDEFINED:
return "ATTR_PREDEFINED"
case ATTR_TYPE_VALUE:
return "ATTR_TYPE_VALUE"
case ATTR_TYPEOF_VALUE:
return "ATTR_TYPEOF_VALUE"
case ATTR_IOTA:
return "ATTR_IOTA"
case ATTR_LOOP_DEFINES:
return "ATTR_LOOP_DEFINES" // []Name defined within loops.
case ATTR_LOOP_USES:
return "ATTR_LOOP_USES" // []Name loop defines actually used.
case ATTR_SHIFT_RHS:
return "ATTR_SHIFT_RHS"
case ATTR_LAST_BLOCK_STMT:
return "ATTR_LAST_BLOCK_STMT"
case ATTR_GLOBAL:
return "ATTR_GLOBAL"
default:
panic(fmt.Sprintf("Unknown attribute: %d", ga))

Check warning on line 186 in gnovm/pkg/gnolang/nodes.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/nodes.go#L163-L186

Added lines #L163 - L186 were not covered by tests
}
}

type Attributes struct {
Line int
Column int
Label Name
data []*attrKV // not persisted

// TODO: if ever the number of attributes ATTR_* grows
// to say more than 100 (rough guess), you can then
// consider using a map for it instead of a slice
// Please see https://github.com/gnolang/gno/issues/3436
data []*attrKV // not persisted
}

func (attr *Attributes) GetLine() int {
Expand Down Expand Up @@ -218,10 +250,6 @@ type attrKV struct {
}

func (attr *Attributes) SetAttribute(key GnoAttribute, value interface{}) {
if attr.data == nil {
attr.data = make([]*attrKV, 0, 4)
}

for _, kv := range attr.data {
if kv.key == key {
kv.value = value
Expand All @@ -233,9 +261,6 @@ func (attr *Attributes) SetAttribute(key GnoAttribute, value interface{}) {
}

func (attr *Attributes) DelAttribute(key GnoAttribute) {
if debug && attr.data == nil {
panic("should not happen, attribute is expected to be non-empty.")
}
_, index, _ := attr.getAttribute(key)
if index < 0 {
return
Expand Down
26 changes: 14 additions & 12 deletions gnovm/pkg/gnolang/nodes_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package gnolang_test

import (
"fmt"
"math"
"testing"

Expand Down Expand Up @@ -46,19 +45,20 @@ func TestStaticBlock_Define2_MaxNames(t *testing.T) {

func TestAttributesSetGetDel(t *testing.T) {
attrs := new(gnolang.Attributes)
if got, want := attrs.GetAttribute("a"), (any)(nil); got != want {
key := gnolang.ATTR_IOTA
if got, want := attrs.GetAttribute(key), (any)(nil); got != want {
t.Errorf(".Get returned an unexpected value=%v, want=%v", got, want)
}
attrs.SetAttribute("a", 10)
if got, want := attrs.GetAttribute("a"), 10; got != want {
attrs.SetAttribute(key, 10)
if got, want := attrs.GetAttribute(key), 10; got != want {
t.Errorf(".Get returned an unexpected value=%v, want=%v", got, want)
}
attrs.SetAttribute("a", 20)
if got, want := attrs.GetAttribute("a"), 20; got != want {
attrs.SetAttribute(key, 20)
if got, want := attrs.GetAttribute(key), 20; got != want {
t.Errorf(".Get returned an unexpected value=%v, want=%v", got, want)
}
attrs.DelAttribute("a")
if got, want := attrs.GetAttribute("a"), (any)(nil); got != want {
attrs.DelAttribute(key)
if got, want := attrs.GetAttribute(key), (any)(nil); got != want {
t.Errorf(".Get returned an unexpected value=%v, want=%v", got, want)
}
}
Expand All @@ -69,20 +69,22 @@ func BenchmarkAttributesSetGetDel(b *testing.B) {
n := 100
keys := make([]gnolang.GnoAttribute, 0, n)
for i := 0; i < n; i++ {
keys = append(keys, gnolang.GnoAttribute(fmt.Sprintf("%d", i)))
keys = append(keys, gnolang.GnoAttribute(i))
}

attrCommon := gnolang.ATTR_TYPEOF_VALUE

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
attrs := new(gnolang.Attributes)
for j := 0; j < 100; j++ {
sink = attrs.GetAttribute("a")
sink = attrs.GetAttribute(attrCommon)
}
for j := 0; j < 100; j++ {
attrs.SetAttribute("a", j)
sink = attrs.GetAttribute("a")
attrs.SetAttribute(attrCommon, j)
sink = attrs.GetAttribute(attrCommon)
}

for j, key := range keys {
Expand Down

0 comments on commit b8646c9

Please sign in to comment.