On Dec 23, 2006, at 11:23 AM, Ed Leafe wrote:

>       I always like to make sure that I know just what the problem is
> before determining what the best solution is. Profiling has usually
> verified my hunches, but has also revealed that the main bottleneck
> was not exactly what I had assumed.

        OK, I downloaded the latest OneToManyApp, and added the @profile  
decorator to dBizobj.requery(). I then requeried with no filters, and  
then skipped through the Customer data so that the child data was  
requeried. Here's the output:

*** PROFILER RESULTS ***
requery (/Library/Frameworks/Python.framework/Versions/2.4/lib/ 
python2.4/site-packages/dabo/biz/dBizobj.py:614)
function called 34 times

          39339 function calls (38896 primitive calls) in 0.650 CPU  
seconds

    Ordered by: cumulative time, internal time, call count
    List reduced from 208 to 40 due to restriction <40>

    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     34/33    0.010    0.000    0.650    0.020 dBizobj.py:614(requery)
        33    0.000    0.000    0.650    0.020 profile:0(<function  
requery at 0x789eb0>)
        34    0.000    0.000    0.550    0.016 dCursorMixin.py:306 
(requery)
        35    0.020    0.001    0.490    0.014 dCursorMixin.py:203 
(execute)
        35    0.010    0.000    0.290    0.008 cursors.py:308(_query)
        35    0.000    0.000    0.290    0.008 cursors.py:127(execute)
        35    0.010    0.000    0.270    0.008 :0(fetch_row)
        35    0.000    0.000    0.270    0.008 cursors.py:279 
(_fetch_row)
        35    0.000    0.000    0.270    0.008 cursors.py:313 
(_post_get_result)
       441    0.020    0.000    0.200    0.000 decimal.py:473(__new__)
      2436    0.070    0.000    0.170    0.000 dCursorMixin.py:145 
(correctFieldType)
       441    0.040    0.000    0.110    0.000 decimal.py:3034 
(_string2exact)
       357    0.060    0.000    0.060    0.000 times.py:73(Date_or_None)
      2436    0.040    0.000    0.060    0.000 __init__.py:61 
(getDaboType)
      7707    0.050    0.000    0.050    0.000 :0(isinstance)
    507/66    0.020    0.000    0.050    0.001 dCursorMixin.py:1210 
(addMemento)
        69    0.010    0.000    0.040    0.001 dBizobj.py:1061(getPK)
        34    0.000    0.000    0.040    0.001 dBizobj.py:800(_moveToPK)
        34    0.020    0.001    0.030    0.001 dCursorMixin.py:1268 
(moveToPK)
        19    0.010    0.001    0.030    0.002 dLocalize.py:30 
(__add_apptrans)
        69    0.000    0.000    0.030    0.000 dCursorMixin.py:690 
(getFieldVal)
        19    0.000    0.000    0.030    0.002 dLocalize.py:46(_)
       441    0.020    0.000    0.020    0.000 decimal.py:2925 
(_isinfinity)
      1764    0.020    0.000    0.020    0.000 :0(group)
        34    0.010    0.000    0.020    0.001 dBizobj.py:671 
(setChildLinkFilter)
      1233    0.010    0.000    0.020    0.000 dCursorMixin.py:1870 
(_getEncoding)
      3049    0.020    0.000    0.020    0.000 :0(get)
       884    0.020    0.000    0.020    0.000 :0(len)
       441    0.020    0.000    0.020    0.000 decimal.py:2933(_isnan)
       441    0.020    0.000    0.020    0.000 :0(map)
       152    0.010    0.000    0.020    0.000 UserDict.py:52(get)
        38    0.000    0.000    0.020    0.001 gettext.py:408(find)
        38    0.000    0.000    0.020    0.001 gettext.py:448 
(translation)
        19    0.000    0.000    0.020    0.001 dLocalize.py:8 
(__translation)
       441    0.010    0.000    0.010    0.000 dMemento.py:6(__init__)
        35    0.010    0.000    0.010    0.000 :0(query)
        35    0.000    0.000    0.010    0.000 cursors.py:270(_do_query)
        34    0.000    0.000    0.010    0.000 dBizobj.py:1069 
(getParentPK)
      1548    0.010    0.000    0.010    0.000 dCursorMixin.py:1802 
(_getBackendObject)
       946    0.010    0.000    0.010    0.000 :0(copy)


        addMemento was called 507 times for a cumulative time of 0.05  
seconds out of 0.65 seconds. I don't see anything else on this that  
has to do with the memento system.

        The other place where you thought the system was slowing down was  
when we have to check for changes before requerying, or doing  
anything that would possibly delete unsaved changes. So I profiled  
the dForm.confirmChanges() method. In order to remove the time for  
the 'areYouSure' dialog, I commented out that line and just set  
response=True, forcing the save. Here are those results:


*** PROFILER RESULTS ***
confirmChanges (/Library/Frameworks/Python.framework/Versions/2.4/lib/ 
python2.4/site-packages/dabo/ui/uiwx/dForm.py:85)
function called 3 times

          34257 function calls (33728 primitive calls) in 0.530 CPU  
seconds

    Ordered by: cumulative time, internal time, call count
    List reduced from 349 to 40 due to restriction <40>

    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
         3    0.000    0.000    0.530    0.177 dForm.py:85 
(confirmChanges)
         3    0.000    0.000    0.530    0.177 profile:0(<function  
confirmChanges at 0x42ae8f0>)
     190/4    0.010    0.000    0.520    0.130 dBizobj.py:503(scan)
       272    0.010    0.000    0.460    0.002 dBizobj.py:785 
(_moveToRowNum)
       193    0.020    0.000    0.430    0.002 dBizobj.py:1326 
(_setCurrentCursor)
       193    0.000    0.000    0.430    0.002 dBizobj.py:936 
(setCurrentParent)
        73    0.010    0.000    0.410    0.006 dBizobj.py:121 
(createCursor)
         1    0.000    0.000    0.370    0.370 Form.py:95(save)
       2/1    0.000    0.000    0.360    0.360 dBizobj.py:255(saveAll)
         1    0.000    0.000    0.360    0.360 dForm.py:257(save)
       292    0.000    0.000    0.310    0.001 :0(apply)
       146    0.000    0.000    0.310    0.002 dCursorMixin.py:28 
(__init__)
       146    0.000    0.000    0.310    0.002 dBizobj.py:171(__init__)
       146    0.000    0.000    0.310    0.002 dBackend.py:50(getCursor)
       146    0.000    0.000    0.310    0.002 dConnection.py:37 
(getCursor)
       146    0.160    0.001    0.300    0.002 propertyHelperMixin.py: 
226(getPropertyList)
       146    0.000    0.000    0.300    0.002 dObject.py:35(__init__)
       146    0.000    0.000    0.300    0.002 propertyHelperMixin.py: 
49(_extractKeywordProperties)
    188/86    0.000    0.000    0.160    0.002 dBizobj.py:835 
(isAnyChanged)
      7974    0.070    0.000    0.070    0.000 :0(has_key)
   264/202    0.000    0.000    0.050    0.000 dBizobj.py:854(isChanged)
        73    0.010    0.000    0.040    0.001 dCursorMixin.py:1773 
(_setAutoCommit)
      1934    0.030    0.000    0.030    0.000 :0(append)
        73    0.030    0.000    0.030    0.000 :0(autocommit)
        73    0.020    0.000    0.030    0.000 dBizobj.py:167 
(_getCursorClass)
        73    0.000    0.000    0.030    0.000 dBackend.py:189 
(setAutoCommitStatus)
       949    0.030    0.000    0.030    0.000 :0(dir)
       264    0.010    0.000    0.030    0.000 dCursorMixin.py:608 
(isChanged)
   165/125    0.000    0.000    0.030    0.000 dBizobj.py:844 
(_checkForChanges)
     95/84    0.000    0.000    0.020    0.000 dBizobj.py:284 
(_saveRowIfChanged)
     15/12    0.000    0.000    0.020    0.002 dBizobj.py:1034 
(requeryAllChildren)
        12    0.000    0.000    0.020    0.002 dBizobj.py:1543 
(_setRowNumber)
         3    0.000    0.000    0.020    0.007 dBizobj.py:613(requery)
      1898    0.010    0.000    0.010    0.000 :0(count)
       358    0.010    0.000    0.010    0.000 dBizobj.py:1400 
(_getKeyField)
       281    0.000    0.000    0.010    0.000 dBizobj.py:1059(getPK)
       590    0.010    0.000    0.010    0.000 dCursorMixin.py:1938 
(_getRowNumber)
       306    0.010    0.000    0.010    0.000 :0(register_converter)
       284    0.010    0.000    0.010    0.000 dCursorMixin.py:1944 
(_setRowNumber)
       264    0.010    0.000    0.010    0.000 dCursorMixin.py:627 
(isRowChanged)

        Here we see that dBizobj.isAnyChanged() took 0.16 out of the total  
time of 0.53 seconds; however, all this method does is call scan() on  
the _checkForChanges() method. _checkForChanges() only took 0.03  
seconds, meaning that the bulk of the time used by isAnyChanged was  
for the implementation of the scan loop, not for the actual checking  
of changes!

        A little profiling gives a lot of useful information.

-- Ed Leafe
-- http://leafe.com
-- http://dabodev.com



_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-dev

Reply via email to