Bug 1443230 - Keep hashtable of interface indexes in xpt.py. r=glandium draft
authorAndrew McCreight <continuation@gmail.com>
Mon, 05 Mar 2018 20:56:26 +0000
changeset 763963 4ae2c04246d693339f973aad5cec8e1d227f16d3
parent 763748 a4ef1082c51d5b4508882c22487f6c8de5b35e2a
push id101621
push userbmo:continuation@gmail.com
push dateTue, 06 Mar 2018 23:07:23 +0000
reviewersglandium
bugs1443230
milestone60.0a1
Bug 1443230 - Keep hashtable of interface indexes in xpt.py. r=glandium A lot of time is spent during the final big XPT link determining what the index is for each interface. Changing this to use a map eliminates about 2/3 of the running time. This patch reduces the run time to a little under a second on my local OSX machine. MozReview-Commit-ID: CH4OYXtT19q
xpcom/typelib/xpt/tools/xpt.py
--- a/xpcom/typelib/xpt/tools/xpt.py
+++ b/xpcom/typelib/xpt/tools/xpt.py
@@ -97,16 +97,48 @@ def enum(*names):
     class Foo(object):
         __metaclass__ = M_add_class_attribs(enumerate(names))
 
         def __setattr__(self, name, value):  # this makes it read-only
             raise NotImplementedError
     return Foo()
 
 
+# List with constant time index() and contains() methods.
+class IndexedList(object):
+    def __init__(self, iterable):
+        self._list = []
+        self._index_map = {}
+        for i in iterable:
+            self.append(i)
+
+    def sort(self):
+        self._list.sort()
+        self._index_map = {val: i for i, val in enumerate(self._list)}
+
+    def append(self, val):
+        self._index_map[val] = len(self._list)
+        self._list.append(val)
+
+    def index(self, what):
+        return self._index_map[what]
+
+    def __contains__(self, what):
+        return what in self._index_map
+
+    def __iter__(self):
+        return iter(self._list)
+
+    def __getitem__(self, index):
+        return self._list[index]
+
+    def __len__(self):
+        return len(self._list)
+
+
 # Descriptor types as described in the spec
 class Type(object):
     """
     Data type of a method parameter or return value. Do not instantiate
     this class directly. Rather, use one of its subclasses.
 
     """
     _prefixdescriptor = struct.Struct(">B")
@@ -1145,17 +1177,17 @@ class Typelib(object):
     _header = struct.Struct(">16sBBHIII")
 
     def __init__(self, version=TYPELIB_VERSION, interfaces=[], annotations=[]):
         """
         Instantiate a new Typelib.
 
         """
         self.version = version
-        self.interfaces = list(interfaces)
+        self.interfaces = IndexedList(interfaces)
         self.annotations = list(annotations)
         self.filename = None
 
     @staticmethod
     def iid_to_string(iid):
         """
         Convert a 16-byte IID into a UUID string.