Browse Source

#451 prefer for over foreach when iterating Lists (#483)

Marko Lahma 7 năm trước cách đây
mục cha
commit
d27b17852d

+ 5 - 3
Jint/Engine.cs

@@ -883,12 +883,14 @@ namespace Jint
             }
 
             // process all variable declarations in the current parser scope
-            for (var i = 0; i < variableDeclarations.Count; i++)
+            var variableDeclarationsCount = variableDeclarations.Count;
+            for (var i = 0; i < variableDeclarationsCount; i++)
             {
                 var variableDeclaration = variableDeclarations[i];
-                var declarations  = variableDeclaration.Declarations;
-                foreach (var d in declarations)
+                var declarationsCount = variableDeclaration.Declarations.Count;
+                for (var j = 0; j < declarationsCount; j++)
                 {
+                    var d = variableDeclaration.Declarations[j];
                     var dn = d.Id.As<Identifier>().Name;
                     var varAlreadyDeclared = env.HasBinding(dn);
                     if (!varAlreadyDeclared)

+ 6 - 4
Jint/Native/Array/ArrayConstructor.cs

@@ -100,15 +100,17 @@ namespace Jint.Native.Array
 
                 instance.SetOwnProperty("length", new WritablePropertyDescriptor(length));
             }
-            else if (arguments.Length == 1 && arguments.At(0).IsObject() && arguments.At(0).As<ObjectWrapper>() != null )
+            else if (arguments.Length == 1 && arguments[0] is ObjectWrapper objectWrapper)
             {
-                if (arguments.At(0).As<ObjectWrapper>().Target is IEnumerable enumerable)
+                if (objectWrapper.Target is IEnumerable enumerable)
                 {
                     var jsArray = (ArrayInstance) Engine.Array.Construct(Arguments.Empty);
+                    var tempArray = new JsValue[1];
                     foreach (var item in enumerable)
                     {
-                        var jsItem = JsValue.FromObject(Engine, item);
-                        Engine.Array.PrototypeObject.Push(jsArray, Arguments.From(jsItem));
+                        var jsItem = FromObject(Engine, item);
+                        tempArray[0] = jsItem;
+                        Engine.Array.PrototypeObject.Push(jsArray, tempArray);
                     }
 
                     return jsArray;

+ 6 - 3
Jint/Native/Array/ArrayInstance.cs

@@ -184,8 +184,11 @@ namespace Jint.Native.Array
                         // in the case of sparse arrays, treat each concrete element instead of
                         // iterating over all indexes
                         var keys = new List<uint>(_sparse.Keys);
-                        foreach (var keyIndex in keys)
+                        var keysCount = keys.Count;
+                        for (var i = 0; i < keysCount; i++)
                         {
+                            var keyIndex = keys[i];
+                            
                             // is it the index of the array
                             if (keyIndex >= newLen && keyIndex < oldLen)
                             {
@@ -542,7 +545,7 @@ namespace Jint.Native.Array
             return _sparse.TryGetValue(index, out descriptor);
         }
 
-        private void WriteArrayValue(uint index, IPropertyDescriptor desc)
+        internal void WriteArrayValue(uint index, IPropertyDescriptor desc)
         {
             // calculate eagerly so we know if we outgrow
             var newSize = _dense != null && index >= _dense.Length
@@ -595,4 +598,4 @@ namespace Jint.Native.Array
             }
         }
     }
-}
+}

+ 17 - 8
Jint/Native/JsValue.cs

@@ -8,6 +8,7 @@ using Jint.Native.Date;
 using Jint.Native.Object;
 using Jint.Native.RegExp;
 using Jint.Runtime;
+using Jint.Runtime.Descriptors.Specialized;
 using Jint.Runtime.Interop;
 
 namespace Jint.Native
@@ -204,8 +205,10 @@ namespace Jint.Native
                 return jsValue;
             }
 
-            foreach (var converter in engine.Options._ObjectConverters)
+            var objectConvertersCount = engine.Options._ObjectConverters.Count;
+            for (var i = 0; i < objectConvertersCount; i++)
             {
+                var converter = engine.Options._ObjectConverters[i];
                 if (converter.TryConvert(value, out var result))
                 {
                     return result;
@@ -232,14 +235,19 @@ namespace Jint.Native
             {
                 JsValue Convert(Engine e, object v)
                 {
-                    var array = (System.Array)v;
-
-                    var jsArray = engine.Array.Construct(a.Length);
-                    foreach (var item in array)
+                    var array = (System.Array) v;
+                    var arrayLength = (uint) array.Length;
+
+                    var jsArray = new ArrayInstance(e, arrayLength);
+                    jsArray.Prototype = e.Array.PrototypeObject;
+                    jsArray.Extensible = true;
+                    
+                    for (uint i = 0; i < arrayLength; ++i)
                     {
-                        var jsItem = FromObject(engine, item);
-                        engine.Array.PrototypeObject.Push(jsArray, Arguments.From(jsItem));
+                        var jsItem = FromObject(e, array.GetValue(i));
+                        jsArray.WriteArrayValue(i, new ConfigurableEnumerableWritablePropertyDescriptor(jsItem));
                     }
+                    jsArray.SetOwnProperty("length", new WritablePropertyDescriptor(arrayLength));
 
                     return jsArray;
                 }
@@ -249,6 +257,7 @@ namespace Jint.Native
                 {
                     [valueType] = Convert
                 }, typeMappers);
+
                 return Convert(engine, a);
             }
 
@@ -259,7 +268,7 @@ namespace Jint.Native
 
             if (value.GetType().IsEnum())
             {
-                return JsNumber.Create((int)value);
+                return JsNumber.Create((int) value);
             }
 
             // if no known type could be guessed, wrap it as an ObjectInstance

+ 3 - 2
Jint/Native/String/StringPrototype.cs

@@ -352,9 +352,10 @@ namespace Jint.Native.String
                     {
                         segments.Capacity = s.Length;
                     }
-                    foreach (var c in s)
+
+                    for (var i = 0; i < s.Length; i++)
                     {
-                        segments.Add(TypeConverter.ToString(c));
+                        segments.Add(TypeConverter.ToString(s[i]));
                     }
                 }
                 else

+ 2 - 2
Jint/Options.cs

@@ -165,9 +165,9 @@ namespace Jint
 
         internal Predicate<Exception> _ClrExceptionsHandler => _clrExceptionsHandler;
 
-        internal IList<Assembly> _LookupAssemblies => _lookupAssemblies;
+        internal List<Assembly> _LookupAssemblies => _lookupAssemblies;
 
-        internal IEnumerable<IObjectConverter> _ObjectConverters => _objectConverters;
+        internal List<IObjectConverter> _ObjectConverters => _objectConverters;
 
         internal int _MaxStatements => _maxStatements;
 

+ 10 - 6
Jint/Runtime/ExpressionIntepreter.cs

@@ -658,8 +658,10 @@ namespace Jint.Runtime
             // http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.5
 
             var obj = _engine.Object.Construct(Arguments.Empty);
-            foreach (var property in objectExpression.Properties)
+            var propertiesCount = objectExpression.Properties.Count;
+            for (var i = 0; i < propertiesCount; i++)
             {
+                var property = objectExpression.Properties[i];
                 var propName = property.Key.GetKey();
                 var previous = obj.GetOwnProperty(propName);
                 IPropertyDescriptor propDesc;
@@ -692,7 +694,7 @@ namespace Jint.Runtime
                             );
                         }
 
-                        propDesc = new PropertyDescriptor(get: get, set: null, enumerable: true, configurable:true);
+                        propDesc = new PropertyDescriptor(get: get, set: null, enumerable: true, configurable: true);
                         break;
 
                     case PropertyKind.Set:
@@ -706,15 +708,15 @@ namespace Jint.Runtime
                         ScriptFunctionInstance set;
                         using (new StrictModeScope(setter.Strict))
                         {
-
                             set = new ScriptFunctionInstance(
                                 _engine,
                                 setter,
                                 _engine.ExecutionContext.LexicalEnvironment,
                                 StrictModeScope.IsStrictModeCode
-                                );
+                            );
                         }
-                        propDesc = new PropertyDescriptor(get:null, set: set, enumerable: true, configurable: true);
+
+                        propDesc = new PropertyDescriptor(get: null, set: set, enumerable: true, configurable: true);
                         break;
 
                     default:
@@ -932,8 +934,10 @@ namespace Jint.Runtime
         public JsValue EvaluateSequenceExpression(SequenceExpression sequenceExpression)
         {
             var result = Undefined.Instance;
-            foreach (var expression in sequenceExpression.Expressions)
+            var expressionsCount = sequenceExpression.Expressions.Count;
+            for (var i = 0; i < expressionsCount; i++)
             {
+                var expression = sequenceExpression.Expressions[i];
                 result = _engine.GetValue(_engine.EvaluateExpression(expression.As<Expression>()), true);
             }
 

+ 4 - 4
Jint/Runtime/Interop/NamespaceReference.cs

@@ -88,9 +88,7 @@ namespace Jint.Runtime.Interop
 
         public JsValue GetPath(string path)
         {
-            Type type;
-
-            if (Engine.TypeCache.TryGetValue(path, out type))
+            if (Engine.TypeCache.TryGetValue(path, out var type))
             {
                 if (type == null)
                 {
@@ -108,8 +106,10 @@ namespace Jint.Runtime.Interop
             // search in loaded assemblies
             var lookupAssemblies = new[] {Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly()};
 
-            foreach (var assembly in lookupAssemblies)
+            var lookupAssembliesLength = lookupAssemblies.Length;
+            for (var i = 0; i < lookupAssembliesLength; i++)
             {
+                var assembly = lookupAssemblies[i];
                 type = assembly.GetType(path);
                 if (type != null)
                 {

+ 10 - 4
Jint/Runtime/StatementInterpreter.cs

@@ -383,8 +383,11 @@ namespace Jint.Runtime
             JsValue v = Undefined.Instance;
             SwitchCase defaultCase = null;
             bool hit = false;
-            foreach (var clause in switchBlock)
+
+            var switchBlockCount = switchBlock.Count;
+            for (var i = 0; i < switchBlockCount; i++)
             {
+                var clause = switchBlock[i];
                 if (clause.Test == null)
                 {
                     defaultCase = clause;
@@ -408,7 +411,6 @@ namespace Jint.Runtime
 
                     v = r.Value != null ? r.Value : Undefined.Instance;
                 }
-
             }
 
             // do we need to execute the default case ?
@@ -434,8 +436,10 @@ namespace Jint.Runtime
 
             try
             {
-                foreach (var statement in statementList)
+                var statementListCount = statementList.Count;
+                for (var i = 0; i < statementListCount; i++)
                 {
+                    var statement = statementList[i];
                     s = statement.As<Statement>();
                     c = ExecuteStatement(s);
                     if (c.Type != Completion.Normal)
@@ -526,8 +530,10 @@ namespace Jint.Runtime
 
         public Completion ExecuteVariableDeclaration(VariableDeclaration statement)
         {
-            foreach (var declaration in statement.Declarations)
+            var declarationsCount = statement.Declarations.Count;
+            for (var i = 0; i < declarationsCount; i++)
             {
+                var declaration = statement.Declarations[i];
                 if (declaration.Init != null)
                 {
                     if (!(_engine.EvaluateExpression(declaration.Id.As<Identifier>()) is Reference lhs))