Ver código fonte

Optimised setting of an empty array property

Dmitry Panov 4 anos atrás
pai
commit
1b11a6af68
3 arquivos alterados com 25 adições e 1 exclusões
  1. 12 0
      array_test.go
  2. 9 1
      object.go
  3. 4 0
      object_goreflect.go

+ 12 - 0
array_test.go

@@ -106,3 +106,15 @@ func BenchmarkArrayPut(b *testing.B) {
 	}
 
 }
+
+func BenchmarkArraySetEmpty(b *testing.B) {
+	r := New()
+	r.Get("Array").(*Object).Get("prototype").String() // materialise Array.prototype
+	a := r.NewArray(0, 0)
+	values := a.self.(*arrayObject).values
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		values[0] = nil
+		a.self.setOwnIdx(0, valueTrue, true)
+	}
+}

+ 9 - 1
object.go

@@ -565,7 +565,15 @@ func (o *baseObject) setForeignStr(name unistring.String, val, receiver Value, t
 }
 
 func (o *baseObject) setForeignIdx(name valueInt, val, receiver Value, throw bool) (bool, bool) {
-	return o.val.self.setForeignStr(name.string(), val, receiver, throw)
+	if idx := toIdx(name); idx != math.MaxUint32 {
+		if o.lastSortedPropLen != len(o.propNames) {
+			o.fixPropOrder()
+		}
+		if o.idxPropCount == 0 {
+			return o._setForeignIdx(name, name, nil, receiver, throw)
+		}
+	}
+	return o.setForeignStr(name.string(), val, receiver, throw)
 }
 
 func (o *baseObject) setForeignSym(name *Symbol, val, receiver Value, throw bool) (bool, bool) {

+ 4 - 0
object_goreflect.go

@@ -209,6 +209,10 @@ func (o *objectGoReflect) setForeignStr(name unistring.String, val, receiver Val
 	return o._setForeignStr(name, trueValIfPresent(o._has(name.String())), val, receiver, throw)
 }
 
+func (o *objectGoReflect) setForeignIdx(idx valueInt, val, receiver Value, throw bool) (bool, bool) {
+	return o._setForeignIdx(idx, nil, val, receiver, throw)
+}
+
 func (o *objectGoReflect) _put(name string, val Value, throw bool) (has, ok bool) {
 	if o.value.Kind() == reflect.Struct {
 		if v := o._getField(name); v.IsValid() {