]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- the wrapped memoized_property here was not working, as the attribute name
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 27 Nov 2013 04:24:13 +0000 (23:24 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 27 Nov 2013 04:24:13 +0000 (23:24 -0500)
didn't match.  use straight memoized_props here for now, add a perf test to check it

lib/sqlalchemy/orm/attributes.py
lib/sqlalchemy/orm/dynamic.py
test/aaa_profiling/test_orm.py
test/perf/orm2010.py
test/profiles.txt

index e3c6a3512258594d684b5b7c519d8b156af1bdc4..ce6200e7177e9f8718d89ab609134cd186bf2166 100644 (file)
@@ -355,12 +355,6 @@ class Event(object):
         self.op = op
         self.parent_token = self.impl.parent_token
 
-    @classmethod
-    def _token_gen(self, op):
-        @util.memoized_property
-        def gen(self):
-            return Event(self, op)
-        return gen
 
     @property
     def key(self):
@@ -687,8 +681,17 @@ class ScalarAttributeImpl(AttributeImpl):
         state._modified_event(dict_, self, old)
         dict_[self.key] = value
 
-    _replace_token = _append_token = Event._token_gen(OP_REPLACE)
-    _remove_token = Event._token_gen(OP_REMOVE)
+    @util.memoized_property
+    def _replace_token(self):
+        return Event(self, OP_REPLACE)
+
+    @util.memoized_property
+    def _append_token(self):
+        return Event(self, OP_REPLACE)
+
+    @util.memoized_property
+    def _remove_token(self):
+        return Event(self, OP_REMOVE)
 
     def fire_replace_event(self, state, dict_, value, previous, initiator):
         for fn in self.dispatch.set:
@@ -879,8 +882,13 @@ class CollectionAttributeImpl(AttributeImpl):
 
         return [(instance_state(o), o) for o in current]
 
-    _append_token = Event._token_gen(OP_APPEND)
-    _remove_token = Event._token_gen(OP_REMOVE)
+    @util.memoized_property
+    def _append_token(self):
+        return Event(self, OP_APPEND)
+
+    @util.memoized_property
+    def _remove_token(self):
+        return Event(self, OP_REMOVE)
 
     def fire_append_event(self, state, dict_, value, initiator):
         for fn in self.dispatch.append:
index b419d2a0742287c17ef5cfb6a67fab49967fc684..829cda554bafe29a6d52169156aca26d0531a719 100644 (file)
@@ -76,8 +76,13 @@ class DynamicAttributeImpl(attributes.AttributeImpl):
             history = self._get_collection_history(state, passive)
             return history.added_plus_unchanged
 
-    _append_token = attributes.Event._token_gen(attributes.OP_APPEND)
-    _remove_token = attributes.Event._token_gen(attributes.OP_REMOVE)
+    @util.memoized_property
+    def _append_token(self):
+        return attributes.Event(self, attributes.OP_APPEND)
+
+    @util.memoized_property
+    def _remove_token(self):
+        return attributes.Event(self, attributes.OP_REMOVE)
 
     def fire_append_event(self, state, dict_, value, initiator,
                                                     collection_history=None):
index 6d71468b725f449d4d0221d8830e52835857d722..2c1e84afb0ccee363c2c254a17d8d5701c3863ff 100644 (file)
@@ -310,3 +310,63 @@ class DeferOptionsTest(fixtures.MappedTest):
             *[defer(letter) for letter in ['x', 'y', 'z', 'p', 'q', 'r']]).\
             all()
 
+
+class AttributeOverheadTest(fixtures.MappedTest):
+    @classmethod
+    def define_tables(cls, metadata):
+        Table('parent', metadata, Column('id', Integer,
+                       primary_key=True,
+                       test_needs_autoincrement=True), Column('data',
+                       String(20)))
+        Table('child', metadata, Column('id', Integer,
+                      primary_key=True, test_needs_autoincrement=True),
+                      Column('data', String(20)), Column('parent_id',
+                      Integer, ForeignKey('parent.id'), nullable=False))
+
+    @classmethod
+    def setup_classes(cls):
+        class Parent(cls.Basic):
+            pass
+
+        class Child(cls.Basic):
+            pass
+
+    @classmethod
+    def setup_mappers(cls):
+        Child, Parent, parent, child = (cls.classes.Child,
+                                cls.classes.Parent,
+                                cls.tables.parent,
+                                cls.tables.child)
+
+        mapper(Parent, parent, properties={'children':
+                        relationship(Child, backref='parent')})
+        mapper(Child, child)
+
+
+    def test_attribute_set(self):
+        Parent, Child = self.classes.Parent, self.classes.Child
+        p1 = Parent()
+        c1 = Child()
+
+        @profiling.function_call_count()
+        def go():
+            for i in range(30):
+                c1.parent = p1
+                c1.parent = None
+                c1.parent = p1
+                del c1.parent
+        go()
+
+    def test_collection_append_remove(self):
+        Parent, Child = self.classes.Parent, self.classes.Child
+        p1 = Parent()
+        children = [Child() for i in range(100)]
+
+        @profiling.function_call_count()
+        def go():
+            for child in children:
+                p1.children.append(child)
+            for child in children:
+                p1.children.remove(child)
+        go()
+
index 088563e946d4bfa9f133527a74fea2afcdf0995c..0213458b6efb0abd741124f88728083d09b2bb3f 100644 (file)
@@ -103,9 +103,8 @@ def runit(status, factor=1):
     sess.commit()
     status("Associated grunts w/ bosses and committed")
 
-
     # do some heavier reading
-    for i in range(5):
+    for i in range(int(round(factor / 2.0))):
         status("Heavy query run #%d" % (i + 1))
 
         report = []
@@ -147,7 +146,7 @@ def run_with_profile():
 
     #stats.sort_stats('time', 'calls')
     #stats.print_stats()
-    #os.system("runsnake %s" % filename)
+#    os.system("runsnake %s" % filename)
 
     # SQLA Version: 0.7b1
     # Total calls 4956750
@@ -174,4 +173,5 @@ def run_with_time():
     runit(status, 10)
     print("Total time: %d" % (time.time() - now))
 
-run_with_time()
+run_with_profile()
+#run_with_time()
index 5b17ee8ec393a6f9a4c624d1c2489f2382c1e158..282bc5f4fb3f178ccebaf6db7ab58d0170aa2177 100644 (file)
@@ -99,6 +99,14 @@ test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.3_postgre
 test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.3_postgresql_psycopg2_nocextensions 151
 test.aaa_profiling.test_compiler.CompileTest.test_update_whereclause 3.3_sqlite_pysqlite_cextensions 151
 
+# TEST: test.aaa_profiling.test_orm.AttributeOverheadTest.test_attribute_set
+
+test.aaa_profiling.test_orm.AttributeOverheadTest.test_attribute_set 2.7_sqlite_pysqlite_cextensions 4265
+
+# TEST: test.aaa_profiling.test_orm.AttributeOverheadTest.test_collection_append_remove
+
+test.aaa_profiling.test_orm.AttributeOverheadTest.test_collection_append_remove 2.7_sqlite_pysqlite_cextensions 6525
+
 # TEST: test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline
 
 test.aaa_profiling.test_orm.DeferOptionsTest.test_baseline 2.7_mysql_mysqldb_cextensions 30052