Procházet zdrojové kódy

small performance boost by precomputing lca

Simon Van Mierlo před 9 roky
rodič
revize
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)
 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 author: Yentl Van Tendeloo
 Model name:   HTTP client
 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)
 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 author: Yentl Van Tendeloo
 Model name:   HTTP Server
 Model name:   HTTP Server

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

@@ -69,19 +69,23 @@
 							</transition>
 							</transition>
 						</state>
 						</state>
 						<state id="check_nr_of_fields">
 						<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>
 							<transition target="../waiting" cond="this.nr_of_fields != 0"/>
 							<transition target="../waiting" cond="this.nr_of_fields != 0"/>
 						</state>
 						</state>
+                        <state id="stopped" />
 					</state>
 					</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>
 				</parallel>
 				<state id="stopped" />
 				<state id="stopped" />
 			</state>
 			</state>

+ 8 - 3
examples/bouncingballs/python/Makefile

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

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

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

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

@@ -72,15 +72,12 @@
                             </transition>
                             </transition>
                         </state>
                         </state>
                         <state id="check_nr_of_fields">
                         <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>
                             <transition target="../waiting" cond="self.nr_of_fields != 0"/>
                             <transition target="../waiting" cond="self.nr_of_fields != 0"/>
                         </state>
                         </state>
+                        <state id="stopped" />
                     </state>
                     </state>
                     <state id="spawn_windows" initial="spawning">
                     <state id="spawn_windows" initial="spawning">
                         <state id="spawning">
                         <state id="spawning">
@@ -91,6 +88,13 @@
                             </transition>
                             </transition>
                         </state>
                         </state>
                     </state>
                     </state>
+                    <transition target="../stopped" event="stop">
+                        <script>
+                            <![CDATA[
+                            ui.close_window(ui.window)
+                            ]]>
+                        </script>
+                    </transition>
                 </parallel>
                 </parallel>
                 <state id="stopped" />
                 <state id="stopped" />
             </state>
             </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)
 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 author: Glenn De Jonghe
 Model name:   AI Tank
 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)
 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 author: Glenn De Jonghe
 Model name:   Player Tank
 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) {
 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) {
     var exit_set = this.lca.descendants.slice(0).filter(function(obj) {
         return function(s) {
         return function(s) {
             return obj.obj.configuration.indexOf(s) >= 0;
             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) {
 Transition.prototype.setGuard = function(guard) {
     this.guard = guard.bind(this.obj);
     this.guard = guard.bind(this.obj);
 }
 }
@@ -954,7 +939,17 @@ Transition.prototype.setTrigger = function(trigger) {
 }
 }
 
 
 Transition.prototype.optimize = function() {
 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
 // RuntimeClassBase

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

@@ -766,13 +766,6 @@ class Transition:
         return targets
         return targets
     
     
     def __exitSet(self, 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)]
         return [s for s in reversed(self.lca.descendants) if (s in self.obj.configuration)]
     
     
     def __enterSet(self, targets):
     def __enterSet(self, targets):
@@ -784,9 +777,6 @@ class Transition:
                 yield a
                 yield a
         for target in targets:
         for target in targets:
             yield target
             yield target
-    
-    def conflicts(self, transition):
-        return self.__exitSet(self.__getEffectiveTargetStates()) & transition.__exitSet(transition.__getEffectiveTargetStates())
         
         
     def setGuard(self, guard):
     def setGuard(self, guard):
         self.guard = guard
         self.guard = guard
@@ -800,8 +790,14 @@ class Transition:
             self.source.has_eventless_transitions = True
             self.source.has_eventless_transitions = True
         
         
     def optimize(self):
     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):
     def __repr__(self):
         return "Transition(%i, %s)" % (self.source.state_id, [target.state_id for target in self.targets])
         return "Transition(%i, %s)" % (self.source.state_id, [target.state_id for target in self.targets])