From 6bf88a5c4b6989994f6a2c0ffbc69e337b043951 Mon Sep 17 00:00:00 2001
From: Alexandre Boeglin <alex@nexedi.com>
Date: Fri, 9 Nov 2007 14:55:33 +0000
Subject: [PATCH] as _getTypeBasedMethod can be called a lot within a short
 period for the same method_id on objects with the same portal type (for
 instance, asPredicate, during a predicate search), caching its result is much
 faster than looking for the same script in a nearly identical acquisition
 path each time.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@17492 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Type/Base.py | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/product/ERP5Type/Base.py b/product/ERP5Type/Base.py
index f49a9c4257..1055fa34a4 100644
--- a/product/ERP5Type/Base.py
+++ b/product/ERP5Type/Base.py
@@ -2692,24 +2692,28 @@ class Base( CopyContainer,
 
       fallback_script_id : the script to use if nothing is found
     """
+    def cached_getattr(portal_type, method_id):
+      script_name_end = '_%s' % method_id
+      for script_name_begin in [portal_type, self.getMetaType(),
+          self.__class__.__name__]:
+        name = ''.join([script_name_begin.replace(' ',''), script_name_end])
+        script = getattr(self, name, None)
+        if script is not None:
+          return script
+    cached_getattr = CachingMethod(cached_getattr, id='Base__getattr',
+        cache_factory='erp5_content_long')
     # script_id should not be used any more, keep compatibility
     if script_id is not None:
       LOG('ERP5Type/Base.getTypeBaseMethod',0,
            'DEPRECATED script_id parameter is used')
       fallback_script_id=script_id
-    script_name = ''
-    script = None
-    script_name_end = '_%s' % method_id
     # Look at a local script which
     # can return a new predicate.
-    for script_name_begin in [self.getPortalType(), self.getMetaType(), self.__class__.__name__]:
-      script_name = join([script_name_begin.replace(' ',''), script_name_end ], '')
-      script = getattr(self, script_name, None)
-      if script is not None:
-        break
-    if script is None and fallback_script_id is not None:
-      script = getattr(self, fallback_script_id)
-    return script
+    script = cached_getattr(self.getPortalType(), method_id)
+    if script is not None:
+      return script.__of__(self)
+    if fallback_script_id is not None:
+      return getattr(self, fallback_script_id)
 
   # Predicate handling
   security.declareProtected(Permissions.AccessContentsInformation, 'asPredicate')
-- 
2.30.9