On 08/19/2012 02:52 AM, Francisco Lopes da Silva wrote:
Hi Tobias, here's the data with and without the strings comparisons

[...]

The rate between the two is .293/.145 = 2.02. So the truth is that
nearly all the benefits got in the Format
phase came by avoiding string comparisons, the caching does nearly
nothing /in this case/ because, in
clang_complete, hardly there's double calls for the methods that are
caching results.

Hi Francisco,

you are right. Avoiding string comparisons helps a lot. I did not see it as I was comparing with Gregory's cindex.py version, which also avoids string comparisons due to the use of different data structures. Comparing again, I see that your version is even a little bit faster as the one from Gregory. Also, your patch seems to address this problem more directly.

I would like to push the following two patches. What do you think?

Tobi

>From 6044985d3550218353751c806283a40391171711 Mon Sep 17 00:00:00 2001
From: Tobias Grosser <[email protected]>
Date: Sun, 19 Aug 2012 09:35:28 +0200
Subject: [PATCH 1/2] Add CachedProperty to CompletionChunk

Suggested by:  Francisco Lopes  <[email protected]>
Code in parts from:  Gregory Szorc  <[email protected]>
---
 plugin/clang/cindex.py |   30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/plugin/clang/cindex.py b/plugin/clang/cindex.py
index 59f4608..4fee7fe 100644
--- a/plugin/clang/cindex.py
+++ b/plugin/clang/cindex.py
@@ -138,6 +138,30 @@ class TranslationUnitSaveError(Exception):
 
 ### Structures and Utility Classes ###
 
+class CachedProperty(object):
+    """Decorator that lazy-loads the value of a property.
+
+    The first time the property is accessed, the original property function is
+    executed. The value it returns is set as the new value of that instance's
+    property, replacing the original method.
+    """
+
+    def __init__(self, wrapped):
+        self.wrapped = wrapped
+        try:
+            self.__doc__ = wrapped.__doc__
+        except:
+            pass
+
+    def __get__(self, instance, instance_type=None):
+        if instance is None:
+            return self
+
+        value = self.wrapped(instance)
+        setattr(instance, self.wrapped.__name__, value)
+
+        return value
+
 class _CXString(Structure):
     """Helper for transforming CXString results."""
 
@@ -1637,16 +1661,16 @@ class CompletionChunk:
     def __repr__(self):
         return "{'" + self.spelling + "', " + str(self.kind) + "}"
 
-    @property
+    @CachedProperty
     def spelling(self):
         return lib.clang_getCompletionChunkText(self.cs, self.key).spelling
 
-    @property
+    @CachedProperty
     def kind(self):
         res = lib.clang_getCompletionChunkKind(self.cs, self.key)
         return completionChunkKindMap[res]
 
-    @property
+    @CachedProperty
     def string(self):
         res = lib.clang_getCompletionChunkCompletionString(self.cs, self.key)
 
-- 
1.7.9.5

>From faabbc4993b037a99e7dfc1fcd1b75351645653d Mon Sep 17 00:00:00 2001
From: Tobias Grosser <[email protected]>
Date: Sun, 19 Aug 2012 10:09:27 +0200
Subject: [PATCH 2/2] Avoid string comparisions in CompletionChunk

This gives a large speedup for clang_complete

Contributed by:  Francisco Lopes  <[email protected]>
---
 plugin/clang/cindex.py |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/plugin/clang/cindex.py b/plugin/clang/cindex.py
index 4fee7fe..ced0f27 100644
--- a/plugin/clang/cindex.py
+++ b/plugin/clang/cindex.py
@@ -1667,8 +1667,11 @@ class CompletionChunk:
 
     @CachedProperty
     def kind(self):
-        res = lib.clang_getCompletionChunkKind(self.cs, self.key)
-        return completionChunkKindMap[res]
+        return completionChunkKindMap[self.kind_raw]
+
+    @CachedProperty
+    def kind_raw(self):
+        return lib.clang_getCompletionChunkKind(self.cs, self.key)
 
     @CachedProperty
     def string(self):
@@ -1680,19 +1683,19 @@ class CompletionChunk:
           None
 
     def isKindOptional(self):
-      return self.kind == completionChunkKindMap[0]
+      return self.kind_raw == 0
 
     def isKindTypedText(self):
-      return self.kind == completionChunkKindMap[1]
+      return self.kind_raw == 1
 
     def isKindPlaceHolder(self):
-      return self.kind == completionChunkKindMap[3]
+      return self.kind_raw == 3
 
     def isKindInformative(self):
-      return self.kind == completionChunkKindMap[4]
+      return self.kind_raw == 4
 
     def isKindResultType(self):
-      return self.kind == completionChunkKindMap[15]
+      return self.kind_raw == 15
 
 completionChunkKindMap = {
             0: CompletionChunk.Kind("Optional"),
-- 
1.7.9.5

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to