Browse Source

small performance boost by precomputing lca

Simon Van Mierlo 9 years ago
parent
commit
3b5f6eb39c

+ 1 - 1
examples/HTTP_client/client.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Wed Aug 10 09:45:49 2016
+Date:   Wed Aug 10 11:44:23 2016
 
 Model author: Yentl Van Tendeloo
 Model name:   HTTP client

+ 1 - 1
examples/HTTP_server/server.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Wed Aug 10 09:45:50 2016
+Date:   Wed Aug 10 11:44:23 2016
 
 Model author: Yentl Van Tendeloo
 Model name:   HTTP Server

+ 13 - 9
examples/bouncingballs/js/sccd.xml

@@ -69,19 +69,23 @@
 							</transition>
 						</state>
 						<state id="check_nr_of_fields">
-							<transition target="../../../stopped" cond="this.nr_of_fields == 0">
-								<script>
-									<![CDATA[
-									//NOTE: ideally, this should be ui.close_window(ui.window). we can't do this though 
-									//		  due to a security measure preventing scripts from closing pages they didn't
-									//		  open themselves
-									ui.println('refresh to play again');
-									]]>
-								</script>
+							<transition target="../stopped" cond="this.nr_of_fields == 0">
+                                <raise event="stop" />								
 							</transition>
 							<transition target="../waiting" cond="this.nr_of_fields != 0"/>
 						</state>
+                        <state id="stopped" />
 					</state>
+                    <transition target="../stopped" event="stop">
+                        <script>
+                            <![CDATA[
+                            //NOTE: ideally, this should be ui.close_window(ui.window). we can't do this though 
+                            //		  due to a security measure preventing scripts from closing pages they didn't
+                            //		  open themselves
+                            ui.println('refresh to play again');
+                            ]]>
+                        </script>
+                    </transition>
 				</parallel>
 				<state id="stopped" />
 			</state>

+ 8 - 3
examples/bouncingballs/python/Makefile

@@ -2,11 +2,10 @@
 
 SCCDC = python -m sccd.compiler.sccdc
 FLAGS = -l python -p eventloop
-
-SOURCES = sccd.xml sccd_performance.xml
+FLAGS_THREADS = -l python -p threads
 
 TARGET_DIR = target_py
-TARGETS = $(TARGET_DIR)/target.py $(TARGET_DIR)/target_performance.py
+TARGETS = $(TARGET_DIR)/target.py $(TARGET_DIR)/target_performance.py $(TARGET_DIR)/target_performance_threads.py $(TARGET_DIR)/target_performance_cpu_time.py
 
 
 all: $(TARGET_DIR) $(TARGETS)
@@ -21,6 +20,12 @@ $(TARGET_DIR)/target.py: sccd.xml
 $(TARGET_DIR)/target_performance.py: sccd_performance.xml
 	$(SCCDC) $(FLAGS) -o $@ $<
 
+$(TARGET_DIR)/target_performance_threads.py: sccd_performance_threads.xml
+	$(SCCDC) $(FLAGS_THREADS) -o $@ $<
+
+$(TARGET_DIR)/target_performance_cpu_time.py: sccd_performance_cpu_time.xml
+	$(SCCDC) $(FLAGS_THREADS) -o $@ $<
+
 $(TARGET_DIR):
 	-mkdir $@
 	touch $@/__init__.py

+ 10 - 6
examples/bouncingballs/python/sccd.xml

@@ -72,16 +72,20 @@
                             </transition>
                         </state>
                         <state id="check_nr_of_fields">
-                            <transition target="../../../stopped" cond="self.nr_of_fields == 0" after="0.05">
-                                <script>
-                                    <![CDATA[
-                                    ui.close_window(ui.window)
-                                    ]]>
-                                </script>
+                            <transition target="../stopped" cond="self.nr_of_fields == 0" after="0.05">
+                                <raise event="stop" />
                             </transition>
                             <transition target="../waiting" cond="self.nr_of_fields != 0"/>
                         </state>
+                        <state id="stopped" />
                     </state>
+                    <transition target="../stopped" event="stop">
+                        <script>
+                            <![CDATA[
+                            ui.close_window(ui.window)
+                            ]]>
+                        </script>
+                    </transition>
                 </parallel>
                 <state id="stopped" />
             </state>

+ 10 - 6
examples/bouncingballs/python/sccd_performance.xml

@@ -72,15 +72,12 @@
                             </transition>
                         </state>
                         <state id="check_nr_of_fields">
-                            <transition target="../../../stopped" cond="self.nr_of_fields == 0" after="0.05">
-                                <script>
-                                    <![CDATA[
-                                    ui.close_window(ui.window)
-                                    ]]>
-                                </script>
+                            <transition target="../stopped" cond="self.nr_of_fields == 0" after="0.05">
+                                <raise event="stop" />
                             </transition>
                             <transition target="../waiting" cond="self.nr_of_fields != 0"/>
                         </state>
+                        <state id="stopped" />
                     </state>
                     <state id="spawn_windows" initial="spawning">
                         <state id="spawning">
@@ -91,6 +88,13 @@
                             </transition>
                         </state>
                     </state>
+                    <transition target="../stopped" event="stop">
+                        <script>
+                            <![CDATA[
+                            ui.close_window(ui.window)
+                            ]]>
+                        </script>
+                    </transition>
                 </parallel>
                 <state id="stopped" />
             </state>

+ 1 - 1
examples/tanks/ai_controller.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Wed Aug 10 09:45:50 2016
+Date:   Wed Aug 10 11:44:23 2016
 
 Model author: Glenn De Jonghe
 Model name:   AI Tank

+ 1 - 1
examples/tanks/player_controller.py

@@ -1,7 +1,7 @@
 """
 Generated by Statechart compiler by Glenn De Jonghe, Joeri Exelmans, Simon Van Mierlo, and Yentl Van Tendeloo (for the inspiration)
 
-Date:   Wed Aug 10 09:45:50 2016
+Date:   Wed Aug 10 11:44:24 2016
 
 Model author: Glenn De Jonghe
 Model name:   Player Tank

+ 11 - 16
src/javascript_sccd_runtime/statecharts_core.js

@@ -899,16 +899,6 @@ Transition.prototype.__getEffectiveTargetStates = function() {
 }
 
 Transition.prototype.__exitSet = function(targets) {
-    var target = targets[0];
-    this.lca = this.source.my_parent;
-    if (this.source.my_parent != target.my_parent) { // external
-        for (let a of this.source.ancestors) {
-            if (target.ancestors.indexOf(a) >= 0) {
-                this.lca = a;
-                break;
-            }
-        }
-    }
     var exit_set = this.lca.descendants.slice(0).filter(function(obj) {
         return function(s) {
             return obj.obj.configuration.indexOf(s) >= 0;
@@ -933,11 +923,6 @@ Transition.prototype.__enterSet = function*(targets) {
     }
 }
 
-Transition.prototype.conflicts = function(transition) {
-    // TODO: implement
-    throw new Exception("NOT IMPLEMENTED");
-}
-
 Transition.prototype.setGuard = function(guard) {
     this.guard = guard.bind(this.obj);
 }
@@ -954,7 +939,17 @@ Transition.prototype.setTrigger = function(trigger) {
 }
 
 Transition.prototype.optimize = function() {
-    // TODO: implement many optimizations
+    // the least-common ancestor can be computed statically
+    this.lca = this.source.my_parent;
+    var target = this.targets[0];
+    if (this.source.my_parent != target.my_parent) { // external
+        for (let a of this.source.ancestors) {
+            if (target.ancestors.indexOf(a) >= 0) {
+                this.lca = a;
+                break;
+            }
+        }
+    }
 }
 
 // RuntimeClassBase

+ 8 - 12
src/python_sccd/python_sccd_runtime/statecharts_core.py

@@ -766,13 +766,6 @@ class Transition:
         return targets
     
     def __exitSet(self, targets):
-        target = targets[0]
-        self.lca = self.source.parent
-        if self.source.parent != target.parent: # external
-            for a in self.source.ancestors:
-                if a in target.ancestors:
-                    self.lca = a
-                    break
         return [s for s in reversed(self.lca.descendants) if (s in self.obj.configuration)]
     
     def __enterSet(self, targets):
@@ -784,9 +777,6 @@ class Transition:
                 yield a
         for target in targets:
             yield target
-    
-    def conflicts(self, transition):
-        return self.__exitSet(self.__getEffectiveTargetStates()) & transition.__exitSet(transition.__getEffectiveTargetStates())
         
     def setGuard(self, guard):
         self.guard = guard
@@ -800,8 +790,14 @@ class Transition:
             self.source.has_eventless_transitions = True
         
     def optimize(self):
-        # TODO: many optimizations.
-        pass
+        # the least-common ancestor can be computed statically
+        self.lca = self.source.parent
+        target = self.targets[0]
+        if self.source.parent != target.parent: # external
+            for a in self.source.ancestors:
+                if a in target.ancestors:
+                    self.lca = a
+                    break
         
     def __repr__(self):
         return "Transition(%i, %s)" % (self.source.state_id, [target.state_id for target in self.targets])