Prevent compiling XSLT on each call of GetInstanceList. To be continued. More optimization needed here. 100x would be fine...
authorEdouard Tisserant
Fri, 16 Feb 2018 01:38:34 +0100
changeset 1935 f2b0d849ea77
parent 1934 67b06b30f2bd
child 1936 b85b13b1c2ec
Prevent compiling XSLT on each call of GetInstanceList. To be continued. More optimization needed here. 100x would be fine...
Beremiz.py
PLCControler.py
--- a/Beremiz.py	Wed Feb 14 15:39:27 2018 +0100
+++ b/Beremiz.py	Fri Feb 16 01:38:34 2018 +0100
@@ -47,7 +47,7 @@
         self.buildpath = None
         self.splash = None
         self.splashPath = self.Bpath("images", "splash.png")
-        self.modules= ["BeremizIDE"]
+        self.modules = ["BeremizIDE"]
         self.debug = os.path.exists("BEREMIZ_DEBUG")
 
     def Bpath(self, *args):
--- a/PLCControler.py	Wed Feb 14 15:39:27 2018 +0100
+++ b/PLCControler.py	Fri Feb 16 01:38:34 2018 +0100
@@ -122,6 +122,7 @@
         self.Debug = debug
 
     def resolve(self, url, pubid, context):
+        # TODO stop deepcopy
         lib_name = os.path.basename(url)
         if lib_name in ["project", "stdlib", "extensions"]:
             lib_el = etree.Element(lib_name)
@@ -266,14 +267,35 @@
                     [_BoolValue] * 2, args) + [[]])))
 
 
-class InstancesPathFactory(object):
-    """Helpers object for generating instances path list"""
-    def __init__(self, instances):
-        self.Instances = instances
+class InstancesPathCollector(object):
+    """ object for collecting instances path list"""
+    def __init__(self, controller):
+        self.Instances = []
+        
+        parser = etree.XMLParser()
+        # arbitrary set debug to false, updated later
+        self.resolver = LibraryResolver(controller, debug=False)
+        parser.resolvers.add(self.resolver)
+
+        # TODO compile XSLT once for all at __init__
+        self.instances_path_xslt_tree = etree.XSLT(
+            etree.parse(
+                os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
+                parser),
+            extensions={
+                ("instances_ns", "AddInstance"): self.AddInstance})
 
     def AddInstance(self, context, *args):
         self.Instances.append(args[0][0])
 
+    def Collect(self, root, name, debug):
+        self.resolver.debug = debug
+        self.instances_path_xslt_tree(
+            root, instance_type=etree.XSLT.strparam(name))
+        res = self.Instances
+        self.Instances = []
+        return res
+
 
 class InstanceTagName(object):
     """Helpers object for generating instance tagname"""
@@ -556,6 +578,7 @@
     def __init__(self):
         self.LastNewIndex = 0
         self.Reset()
+        self.InstancesPathCollector = InstancesPathCollector(self)
 
     # Reset PLCControler internal variables
     def Reset(self):
@@ -803,25 +826,10 @@
         return None
 
     def GetInstanceList(self, root, name, debug=False):
-        instances = []
-        project = self.GetProject(debug)
-        if project is not None:
-            factory = InstancesPathFactory(instances)
-
-            parser = etree.XMLParser()
-            parser.resolvers.add(LibraryResolver(self, debug))
-
-            instances_path_xslt_tree = etree.XSLT(
-                etree.parse(
-                    os.path.join(ScriptDirectory, "plcopen", "instances_path.xslt"),
-                    parser),
-                extensions={
-                    ("instances_ns", "AddInstance"): factory.AddInstance})
-
-            instances_path_xslt_tree(
-                root, instance_type=etree.XSLT.strparam(name))
-
-        return instances
+        project = self.GetProject(debug)
+        if project is not None:
+            return self.InstancesPathCollector.Collect(root, name, debug)
+        return []
 
     def SearchPouInstances(self, tagname, debug=False):
         project = self.GetProject(debug)