]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support iteration via index to improve performance
authorJürg Billeter <j@bitron.ch>
Wed, 11 Aug 2010 21:46:41 +0000 (23:46 +0200)
committerJürg Billeter <j@bitron.ch>
Fri, 17 Sep 2010 23:00:13 +0000 (01:00 +0200)
vala/valaforeachstatement.vala

index bc0cf3d079451c4f94bc2ec382e2dc16746303cf..469c51e185c7310595644de9aec700d807c6c414 100644 (file)
@@ -189,9 +189,42 @@ public class Vala.ForeachStatement : Block {
                }
        }
 
+       bool check_with_index (SemanticAnalyzer analyzer, DataType collection_type) {
+               var get_method = collection_type.get_member ("get") as Method;
+               if (get_method == null) {
+                       return false;
+               }
+               if (get_method.get_parameters ().size != 1) {
+                       return false;
+               }
+               var size_property = collection_type.get_member ("size") as Property;
+               if (size_property == null) {
+                       return false;
+               }
+
+               add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_list".printf (variable_name), collection, source_reference), source_reference));
+               add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_size".printf (variable_name), new MemberAccess (new MemberAccess.simple ("_%s_list".printf (variable_name), source_reference), "size", source_reference), source_reference), source_reference));
+               add_statement (new DeclarationStatement (new LocalVariable (null, "_%s_index".printf (variable_name), new UnaryExpression (UnaryOperator.MINUS, new IntegerLiteral ("1", source_reference), source_reference), source_reference), source_reference));
+               var next = new UnaryExpression (UnaryOperator.INCREMENT, new MemberAccess.simple ("_%s_index".printf (variable_name), source_reference), source_reference);
+               var conditional = new BinaryExpression (BinaryOperator.LESS_THAN, next, new MemberAccess.simple ("_%s_size".printf (variable_name), source_reference), source_reference);
+               var loop = new WhileStatement (conditional, body, source_reference);
+               add_statement (loop);
+
+               var get_call = new MethodCall (new MemberAccess (new MemberAccess.simple ("_%s_list".printf (variable_name), source_reference), "get", source_reference), source_reference);
+               get_call.add_argument (new MemberAccess.simple ("_%s_index".printf (variable_name), source_reference));
+               body.insert_statement (0, new DeclarationStatement (new LocalVariable (type_reference, variable_name, get_call, source_reference), source_reference));
+
+               checked = false;
+               return base.check (analyzer);
+       }
+
        bool check_with_iterator (SemanticAnalyzer analyzer, DataType collection_type) {
                use_iterator = true;
 
+               if (check_with_index (analyzer, collection_type)) {
+                       return true;
+               }
+
                var iterator_method = collection_type.get_member ("iterator") as Method;
                if (iterator_method == null) {
                        Report.error (collection.source_reference, "`%s' does not have an `iterator' method".printf (collection_type.to_string ()));