[sqlalchemy] Re: ordering_list performance

2008-09-23 Thread jean-philippe dutreve

My use case is a bit different : new_entries can be placed everywhere
into the existing SA list, not only at the end (actually it depends on
the entry date).

On 22 sep, 21:20, jason kirtland [EMAIL PROTECTED] wrote:
 Ah, looking more closely i see you're replacing self.entries with a
 list, not insorting into a SA list collection- that's totally ok.  It
 might squeeze a little more speed out to do:

 updated_entries = list(self.entries) + new_entries
 base = len(self.entries)
 for idx, entry in enumerate(new_entries):
 entry.position = base + idx
 self.entries = updated_entries

 orderinglist's extend method could be made to do something much like the
 above quite efficiently.

 jason kirtland wrote:
  A warning: that depends on a bug in the C version of bisect.  When given
  a list subclass, it mistakenly ignores the subclass method
  implementations.  The below will break, if and when that's fixed to
  match the pure Python implementation in the standard lib.

  Calling list.extend(account_entries, new_entries) is probably a safe
  alternative.

  *http://bugs.python.org/issue3935

  jean-philippe dutreve wrote:
  What I've done is something like this:

  account_entries = self.entries[:]
  for entry in new_entries:
  insort_right(account_entries, entry)
  for i, entry in enumerate(account_entries):
  entry.position = i
  self.entries = account_entries

  Don't know if it's the right way to do it but it's much faster.

  On 22 sep, 18:41, jason kirtland [EMAIL PROTECTED] wrote:
  I'm sure there is potential for improvement on the current orderinglist
  code- please feel free to send a patch with optimizations you've found
  to the SA trac.

  The orderinglist hasn't changed much since 0.3, but with 0.5 there may
  be entirely new implementations possible.  For example, I could imagine
  one that defers calculation and manipulation of the positioning
  information until a before_flush hook.  That may be perform better, with
  the trade-off that the position attribute can't be trusted to be in sync
  with the list order.

  jean-philippe dutreve wrote:
  Below is the profiling of code that added 1200 items into an
  ordering_list relation. I had to bypass the ordering_list stuff for
  bulk additions in order to have better performance (down to 2
  seconds).
  Hope this post helps to improve this part (using 0.5.0rc1, python 2.5,
  linux i686, 1.5Go RAM)
  SA is rocking!
  jean-philippe
  Time elapsed:  48.4475638866 s
   8875046 function calls (8869157 primitive calls) in 48.443
  CPU seconds
 Ordered by: internal time, call count
 List reduced from 390 to 10 due to restriction 10
 ncalls  tottime  percall  cumtime  percall
  filename:lineno(function)
  1292937/12922507.8790.000   12.1340.000 attributes.py:
  132(__get__)
12410137.6620.000   39.8360.000 orderinglist.py:
  221(_order_entity)
12410135.8700.000   16.9160.000 orderinglist.py:
  202(_get_order_value)
 4408094.5220.0009.5270.000 attributes.py:394(set)
   12364.1980.003   44.0250.036 orderinglist.py:
  208(reorder)
  1299736/12990483.7520.0004.3730.000 attributes.py:
  310(get)
 4482253.3370.0005.1570.000 identity.py:
  208(modified_event)
 4370612.7040.000   14.3310.000 orderinglist.py:
  205(_set_order_value)
 4408092.2250.000   11.7520.000 attributes.py:
  126(__set__)
 4482251.7750.0001.8120.000 attributes.py:
  958(modified_event)
  Function   was called by...
  attributes.py:132(__get__) - domain.py:200(addEntry)
  (1236)   46.741
domain.py:248(__init__)
  (1236)   47.832
domain.py:272(get)(49452)
  0.609
orderinglist.py:
  202(_get_order_value)(1241013)   16.916
  orderinglist.py:221(_order_entity) - orderinglist.py:208(reorder)
  (1240326)   44.025
orderinglist.py:232(append)
  (687)0.013
  orderinglist.py:202(_get_order_value)  - orderinglist.py:
  221(_order_entity)(1241013)   39.836
  attributes.py:394(set) - attributes.py:126(__set__)
  (440809)   11.752
  orderinglist.py:208(reorder)   - orderinglist.py:
  266(__setslice__)(1236)   44.061
  attributes.py:310(get) - attributes.py:132(__get__)
  (1292937)   12.134
attributes.py:
  347(get_committed_value)(1)0.000
attributes.py:500(set)
  (3708)0.367
attributes.py:
  837(value_as_iterable)(3090)0.108
  identity.py:208(modified_event)- attributes.py:394(set)
  (440809)9.527
 

[sqlalchemy] Re: ordering_list performance

2008-09-22 Thread jason kirtland

I'm sure there is potential for improvement on the current orderinglist 
code- please feel free to send a patch with optimizations you've found 
to the SA trac.

The orderinglist hasn't changed much since 0.3, but with 0.5 there may 
be entirely new implementations possible.  For example, I could imagine 
one that defers calculation and manipulation of the positioning 
information until a before_flush hook.  That may be perform better, with 
the trade-off that the position attribute can't be trusted to be in sync 
with the list order.


jean-philippe dutreve wrote:
 Below is the profiling of code that added 1200 items into an
 ordering_list relation. I had to bypass the ordering_list stuff for
 bulk additions in order to have better performance (down to 2
 seconds).
 Hope this post helps to improve this part (using 0.5.0rc1, python 2.5,
 linux i686, 1.5Go RAM)
 
 SA is rocking!
 jean-philippe
 
 Time elapsed:  48.4475638866 s
  8875046 function calls (8869157 primitive calls) in 48.443
 CPU seconds
 
Ordered by: internal time, call count
List reduced from 390 to 10 due to restriction 10
 
ncalls  tottime  percall  cumtime  percall
 filename:lineno(function)
 1292937/12922507.8790.000   12.1340.000 attributes.py:
 132(__get__)
   12410137.6620.000   39.8360.000 orderinglist.py:
 221(_order_entity)
   12410135.8700.000   16.9160.000 orderinglist.py:
 202(_get_order_value)
4408094.5220.0009.5270.000 attributes.py:394(set)
  12364.1980.003   44.0250.036 orderinglist.py:
 208(reorder)
 1299736/12990483.7520.0004.3730.000 attributes.py:
 310(get)
4482253.3370.0005.1570.000 identity.py:
 208(modified_event)
4370612.7040.000   14.3310.000 orderinglist.py:
 205(_set_order_value)
4408092.2250.000   11.7520.000 attributes.py:
 126(__set__)
4482251.7750.0001.8120.000 attributes.py:
 958(modified_event)
 
 
 
 Function   was called by...
 attributes.py:132(__get__) - domain.py:200(addEntry)
 (1236)   46.741
   domain.py:248(__init__)
 (1236)   47.832
   domain.py:272(get)(49452)
 0.609
   orderinglist.py:
 202(_get_order_value)(1241013)   16.916
 orderinglist.py:221(_order_entity) - orderinglist.py:208(reorder)
 (1240326)   44.025
   orderinglist.py:232(append)
 (687)0.013
 orderinglist.py:202(_get_order_value)  - orderinglist.py:
 221(_order_entity)(1241013)   39.836
 attributes.py:394(set) - attributes.py:126(__set__)
 (440809)   11.752
 orderinglist.py:208(reorder)   - orderinglist.py:
 266(__setslice__)(1236)   44.061
 attributes.py:310(get) - attributes.py:132(__get__)
 (1292937)   12.134
   attributes.py:
 347(get_committed_value)(1)0.000
   attributes.py:500(set)
 (3708)0.367
   attributes.py:
 837(value_as_iterable)(3090)0.108
 identity.py:208(modified_event)- attributes.py:394(set)
 (440809)9.527
   attributes.py:
 525(fire_replace_event)(3708)0.236
   attributes.py:
 579(fire_append_event)(3708)1.960
 orderinglist.py:205(_set_order_value)  - orderinglist.py:
 221(_order_entity)(437061)   39.836
 attributes.py:126(__set__) - domain.py:
 237(_set_attributes)(1276)0.079
   domain.py:255(update)
 (2472)0.089
   orderinglist.py:
 205(_set_order_value)(437061)   14.331
 attributes.py:958(modified_event)  - identity.py:
 208(modified_event)(448225)5.157
  


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: ordering_list performance

2008-09-22 Thread jean-philippe dutreve

What I've done is something like this:

account_entries = self.entries[:]
for entry in new_entries:
insort_right(account_entries, entry)
for i, entry in enumerate(account_entries):
entry.position = i
self.entries = account_entries

Don't know if it's the right way to do it but it's much faster.

On 22 sep, 18:41, jason kirtland [EMAIL PROTECTED] wrote:
 I'm sure there is potential for improvement on the current orderinglist
 code- please feel free to send a patch with optimizations you've found
 to the SA trac.

 The orderinglist hasn't changed much since 0.3, but with 0.5 there may
 be entirely new implementations possible.  For example, I could imagine
 one that defers calculation and manipulation of the positioning
 information until a before_flush hook.  That may be perform better, with
 the trade-off that the position attribute can't be trusted to be in sync
 with the list order.

 jean-philippe dutreve wrote:
  Below is the profiling of code that added 1200 items into an
  ordering_list relation. I had to bypass the ordering_list stuff for
  bulk additions in order to have better performance (down to 2
  seconds).
  Hope this post helps to improve this part (using 0.5.0rc1, python 2.5,
  linux i686, 1.5Go RAM)

  SA is rocking!
  jean-philippe

  Time elapsed:  48.4475638866 s
           8875046 function calls (8869157 primitive calls) in 48.443
  CPU seconds

     Ordered by: internal time, call count
     List reduced from 390 to 10 due to restriction 10

     ncalls  tottime  percall  cumtime  percall
  filename:lineno(function)
  1292937/1292250    7.879    0.000   12.134    0.000 attributes.py:
  132(__get__)
    1241013    7.662    0.000   39.836    0.000 orderinglist.py:
  221(_order_entity)
    1241013    5.870    0.000   16.916    0.000 orderinglist.py:
  202(_get_order_value)
     440809    4.522    0.000    9.527    0.000 attributes.py:394(set)
       1236    4.198    0.003   44.025    0.036 orderinglist.py:
  208(reorder)
  1299736/1299048    3.752    0.000    4.373    0.000 attributes.py:
  310(get)
     448225    3.337    0.000    5.157    0.000 identity.py:
  208(modified_event)
     437061    2.704    0.000   14.331    0.000 orderinglist.py:
  205(_set_order_value)
     440809    2.225    0.000   11.752    0.000 attributes.py:
  126(__set__)
     448225    1.775    0.000    1.812    0.000 attributes.py:
  958(modified_event)

  Function                               was called by...
  attributes.py:132(__get__)             - domain.py:200(addEntry)
  (1236)   46.741
                                            domain.py:248(__init__)
  (1236)   47.832
                                            domain.py:272(get)(49452)
  0.609
                                            orderinglist.py:
  202(_get_order_value)(1241013)   16.916
  orderinglist.py:221(_order_entity)     - orderinglist.py:208(reorder)
  (1240326)   44.025
                                            orderinglist.py:232(append)
  (687)    0.013
  orderinglist.py:202(_get_order_value)  - orderinglist.py:
  221(_order_entity)(1241013)   39.836
  attributes.py:394(set)                 - attributes.py:126(__set__)
  (440809)   11.752
  orderinglist.py:208(reorder)           - orderinglist.py:
  266(__setslice__)(1236)   44.061
  attributes.py:310(get)                 - attributes.py:132(__get__)
  (1292937)   12.134
                                            attributes.py:
  347(get_committed_value)(1)    0.000
                                            attributes.py:500(set)
  (3708)    0.367
                                            attributes.py:
  837(value_as_iterable)(3090)    0.108
  identity.py:208(modified_event)        - attributes.py:394(set)
  (440809)    9.527
                                            attributes.py:
  525(fire_replace_event)(3708)    0.236
                                            attributes.py:
  579(fire_append_event)(3708)    1.960
  orderinglist.py:205(_set_order_value)  - orderinglist.py:
  221(_order_entity)(437061)   39.836
  attributes.py:126(__set__)             - domain.py:
  237(_set_attributes)(1276)    0.079
                                            domain.py:255(update)
  (2472)    0.089
                                            orderinglist.py:
  205(_set_order_value)(437061)   14.331
  attributes.py:958(modified_event)      - identity.py:
  208(modified_event)(448225)    5.157
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: ordering_list performance

2008-09-22 Thread jason kirtland

A warning: that depends on a bug in the C version of bisect.  When given 
a list subclass, it mistakenly ignores the subclass method 
implementations.  The below will break, if and when that's fixed to 
match the pure Python implementation in the standard lib.

Calling list.extend(account_entries, new_entries) is probably a safe 
alternative.

* http://bugs.python.org/issue3935

jean-philippe dutreve wrote:
 What I've done is something like this:
 
 account_entries = self.entries[:]
 for entry in new_entries:
 insort_right(account_entries, entry)
 for i, entry in enumerate(account_entries):
 entry.position = i
 self.entries = account_entries
 
 Don't know if it's the right way to do it but it's much faster.
 
 On 22 sep, 18:41, jason kirtland [EMAIL PROTECTED] wrote:
 I'm sure there is potential for improvement on the current orderinglist
 code- please feel free to send a patch with optimizations you've found
 to the SA trac.

 The orderinglist hasn't changed much since 0.3, but with 0.5 there may
 be entirely new implementations possible.  For example, I could imagine
 one that defers calculation and manipulation of the positioning
 information until a before_flush hook.  That may be perform better, with
 the trade-off that the position attribute can't be trusted to be in sync
 with the list order.

 jean-philippe dutreve wrote:
 Below is the profiling of code that added 1200 items into an
 ordering_list relation. I had to bypass the ordering_list stuff for
 bulk additions in order to have better performance (down to 2
 seconds).
 Hope this post helps to improve this part (using 0.5.0rc1, python 2.5,
 linux i686, 1.5Go RAM)
 SA is rocking!
 jean-philippe
 Time elapsed:  48.4475638866 s
  8875046 function calls (8869157 primitive calls) in 48.443
 CPU seconds
Ordered by: internal time, call count
List reduced from 390 to 10 due to restriction 10
ncalls  tottime  percall  cumtime  percall
 filename:lineno(function)
 1292937/12922507.8790.000   12.1340.000 attributes.py:
 132(__get__)
   12410137.6620.000   39.8360.000 orderinglist.py:
 221(_order_entity)
   12410135.8700.000   16.9160.000 orderinglist.py:
 202(_get_order_value)
4408094.5220.0009.5270.000 attributes.py:394(set)
  12364.1980.003   44.0250.036 orderinglist.py:
 208(reorder)
 1299736/12990483.7520.0004.3730.000 attributes.py:
 310(get)
4482253.3370.0005.1570.000 identity.py:
 208(modified_event)
4370612.7040.000   14.3310.000 orderinglist.py:
 205(_set_order_value)
4408092.2250.000   11.7520.000 attributes.py:
 126(__set__)
4482251.7750.0001.8120.000 attributes.py:
 958(modified_event)
 Function   was called by...
 attributes.py:132(__get__) - domain.py:200(addEntry)
 (1236)   46.741
   domain.py:248(__init__)
 (1236)   47.832
   domain.py:272(get)(49452)
 0.609
   orderinglist.py:
 202(_get_order_value)(1241013)   16.916
 orderinglist.py:221(_order_entity) - orderinglist.py:208(reorder)
 (1240326)   44.025
   orderinglist.py:232(append)
 (687)0.013
 orderinglist.py:202(_get_order_value)  - orderinglist.py:
 221(_order_entity)(1241013)   39.836
 attributes.py:394(set) - attributes.py:126(__set__)
 (440809)   11.752
 orderinglist.py:208(reorder)   - orderinglist.py:
 266(__setslice__)(1236)   44.061
 attributes.py:310(get) - attributes.py:132(__get__)
 (1292937)   12.134
   attributes.py:
 347(get_committed_value)(1)0.000
   attributes.py:500(set)
 (3708)0.367
   attributes.py:
 837(value_as_iterable)(3090)0.108
 identity.py:208(modified_event)- attributes.py:394(set)
 (440809)9.527
   attributes.py:
 525(fire_replace_event)(3708)0.236
   attributes.py:
 579(fire_append_event)(3708)1.960
 orderinglist.py:205(_set_order_value)  - orderinglist.py:
 221(_order_entity)(437061)   39.836
 attributes.py:126(__set__) - domain.py:
 237(_set_attributes)(1276)0.079
   domain.py:255(update)
 (2472)0.089
   orderinglist.py:
 205(_set_order_value)(437061)   14.331
 attributes.py:958(modified_event)  - identity.py:
 208(modified_event)(448225)5.157
  


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to 

[sqlalchemy] Re: ordering_list performance

2008-09-22 Thread jason kirtland

Ah, looking more closely i see you're replacing self.entries with a 
list, not insorting into a SA list collection- that's totally ok.  It 
might squeeze a little more speed out to do:

updated_entries = list(self.entries) + new_entries
base = len(self.entries)
for idx, entry in enumerate(new_entries):
entry.position = base + idx
self.entries = updated_entries

orderinglist's extend method could be made to do something much like the 
above quite efficiently.

jason kirtland wrote:
 A warning: that depends on a bug in the C version of bisect.  When given 
 a list subclass, it mistakenly ignores the subclass method 
 implementations.  The below will break, if and when that's fixed to 
 match the pure Python implementation in the standard lib.
 
 Calling list.extend(account_entries, new_entries) is probably a safe 
 alternative.
 
 * http://bugs.python.org/issue3935
 
 jean-philippe dutreve wrote:
 What I've done is something like this:

 account_entries = self.entries[:]
 for entry in new_entries:
 insort_right(account_entries, entry)
 for i, entry in enumerate(account_entries):
 entry.position = i
 self.entries = account_entries

 Don't know if it's the right way to do it but it's much faster.

 On 22 sep, 18:41, jason kirtland [EMAIL PROTECTED] wrote:
 I'm sure there is potential for improvement on the current orderinglist
 code- please feel free to send a patch with optimizations you've found
 to the SA trac.

 The orderinglist hasn't changed much since 0.3, but with 0.5 there may
 be entirely new implementations possible.  For example, I could imagine
 one that defers calculation and manipulation of the positioning
 information until a before_flush hook.  That may be perform better, with
 the trade-off that the position attribute can't be trusted to be in sync
 with the list order.

 jean-philippe dutreve wrote:
 Below is the profiling of code that added 1200 items into an
 ordering_list relation. I had to bypass the ordering_list stuff for
 bulk additions in order to have better performance (down to 2
 seconds).
 Hope this post helps to improve this part (using 0.5.0rc1, python 2.5,
 linux i686, 1.5Go RAM)
 SA is rocking!
 jean-philippe
 Time elapsed:  48.4475638866 s
  8875046 function calls (8869157 primitive calls) in 48.443
 CPU seconds
Ordered by: internal time, call count
List reduced from 390 to 10 due to restriction 10
ncalls  tottime  percall  cumtime  percall
 filename:lineno(function)
 1292937/12922507.8790.000   12.1340.000 attributes.py:
 132(__get__)
   12410137.6620.000   39.8360.000 orderinglist.py:
 221(_order_entity)
   12410135.8700.000   16.9160.000 orderinglist.py:
 202(_get_order_value)
4408094.5220.0009.5270.000 attributes.py:394(set)
  12364.1980.003   44.0250.036 orderinglist.py:
 208(reorder)
 1299736/12990483.7520.0004.3730.000 attributes.py:
 310(get)
4482253.3370.0005.1570.000 identity.py:
 208(modified_event)
4370612.7040.000   14.3310.000 orderinglist.py:
 205(_set_order_value)
4408092.2250.000   11.7520.000 attributes.py:
 126(__set__)
4482251.7750.0001.8120.000 attributes.py:
 958(modified_event)
 Function   was called by...
 attributes.py:132(__get__) - domain.py:200(addEntry)
 (1236)   46.741
   domain.py:248(__init__)
 (1236)   47.832
   domain.py:272(get)(49452)
 0.609
   orderinglist.py:
 202(_get_order_value)(1241013)   16.916
 orderinglist.py:221(_order_entity) - orderinglist.py:208(reorder)
 (1240326)   44.025
   orderinglist.py:232(append)
 (687)0.013
 orderinglist.py:202(_get_order_value)  - orderinglist.py:
 221(_order_entity)(1241013)   39.836
 attributes.py:394(set) - attributes.py:126(__set__)
 (440809)   11.752
 orderinglist.py:208(reorder)   - orderinglist.py:
 266(__setslice__)(1236)   44.061
 attributes.py:310(get) - attributes.py:132(__get__)
 (1292937)   12.134
   attributes.py:
 347(get_committed_value)(1)0.000
   attributes.py:500(set)
 (3708)0.367
   attributes.py:
 837(value_as_iterable)(3090)0.108
 identity.py:208(modified_event)- attributes.py:394(set)
 (440809)9.527
   attributes.py:
 525(fire_replace_event)(3708)0.236
   attributes.py:
 579(fire_append_event)(3708)1.960
 orderinglist.py:205(_set_order_value)  - orderinglist.py:
 221(_order_entity)(437061)   39.836
 attributes.py:126(__set__) - domain.py: