[python-win32] Python win32Com Server DLL

Stephen Chapman schapman1974 at gmail.com
Tue Feb 7 11:09:18 EST 2017


Hello,
   I am having a speed issue while running dll functions.  I have a minimal
com server example and a minimal com client example below.  I have added
cProfile to the example.  All source files and the profile are attached.

   So when I run this example I get between 1.4 seconds to 1.7 seconds.  I
am running a loop of 10,000 doing 2 methods in the loop.  So the here are a
couple lines from the profile.

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.050    0.050    1.740    1.740
cpminimaltest.py:6(testcalltime)
    20001    0.103    0.000    1.689    0.000 dynamic.py:41(__call__)
    20004    0.698    0.000    1.247    0.000 automation.py:702(Invoke)
    80001    0.276    0.000    0.313    0.000 automation.py:197(_set_value)

It seems like the Invoke is taking an inordinate amount of time.  When I
create a minimal example in C# and run the same test.  I get .009
seconds.   Is there something I am not doing right.  Would having a tlb
file attached help?...


<minimal server example>
from win32com.server import register
import sys
import pstats
import cProfile

class dataObject(object):
    _public_methods_  = ["method1","method2","startProfile","printStats"]
    _public_attrs_    = []
    _reg_progid_      = "testcall.dataobject"
    _reg_desc_        = "simple test project"
    _reg_clsid_       = "{97dbc38f-44ce-11e2-a5e5-001018107395}"

    def __init__(self):
        self.profile = cProfile.Profile()

    def method1(self,*args):
        return 0

    def method2(self,*args):
        return 0

    def startProfile(self):
        self.profile.enable()

    def printStats(self,filename=""):
        self.profile.disable()
        f = open(filename, 'w')
        sortby = 'cumulative'
        try:
            pstats.Stats(self.profile,
stream=f).strip_dirs().sort_stats(sortby).print_stats()
        except:
            f.write("Nothing was profiled\n")
        f.close()

if __name__=='__main__':
    if len(sys.argv)>1:
        register.UnregisterServer(dataObject)
    else:
        register.UseCommandLine(dataObject)


<minimal client example>
from comtypes.client import CreateObject
import time

do = CreateObject("testcall.dataobject")

def testcalltime():
    c4 = 0
    a=time.time()
    for d in range (0,10000):
        d=do.method1(c4,1)
        e=do.method2(c4,1)
    b=time.time()
    print b-a

do.startProfile()
testcalltime()
do.printStats("c:\profile.txt")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-win32/attachments/20170207/8c340ff0/attachment.html>
-------------- next part --------------
         742147 function calls (742109 primitive calls) in 1.810 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.050    0.050    1.740    1.740 cpminimaltest.py:6(testcalltime)
    20001    0.103    0.000    1.689    0.000 dynamic.py:41(__call__)
    20004    0.698    0.000    1.247    0.000 automation.py:702(Invoke)
    80001    0.276    0.000    0.313    0.000 automation.py:197(_set_value)
    20004    0.156    0.000    0.285    0.000 automation.py:632(__del__)
    20004    0.043    0.000    0.147    0.000 policy.py:266(_Invoke_)
    20004    0.029    0.000    0.104    0.000 policy.py:279(_invoke_)
   100005    0.096    0.000    0.096    0.000 automation.py:169(__del__)
    20004    0.057    0.000    0.075    0.000 policy.py:568(_invokeex_)
    20004    0.046    0.000    0.072    0.000 automation.py:525(from_param)
        1    0.001    0.001    0.069    0.069 __init__.py:9(<module>)
   140059    0.057    0.000    0.057    0.000 {isinstance}
        1    0.010    0.010    0.054    0.054 gencache.py:22(<module>)
        1    0.000    0.000    0.043    0.043 gencache.py:53(__init__)
    20001    0.043    0.000    0.043    0.000 automation.py:338(_get_value)
        1    0.000    0.000    0.043    0.043 gencache.py:73(_LoadDicts)
        2    0.043    0.021    0.043    0.021 {built-in method load}
    20011    0.020    0.000    0.020    0.000 {range}
    80016    0.019    0.000    0.019    0.000 {_ctypes.byref}
        1    0.001    0.001    0.014    0.014 dynamic.py:17(<module>)
        1    0.009    0.009    0.013    0.013 build.py:11(<module>)
    20001    0.011    0.000    0.011    0.000 {getattr}
    40011    0.009    0.000    0.009    0.000 {method 'pop' of 'dict' objects}
40735/40732    0.008    0.000    0.008    0.000 {len}
    20004    0.006    0.000    0.006    0.000 {_ctypes.POINTER}
    20004    0.006    0.000    0.006    0.000 automation.py:165(__init__)
        1    0.000    0.000    0.004    0.004 string.py:20(<module>)
        2    0.000    0.000    0.003    0.002 re.py:188(compile)
        2    0.000    0.000    0.003    0.002 re.py:226(_compile)
        2    0.000    0.000    0.003    0.002 sre_compile.py:493(compile)
        1    0.000    0.000    0.003    0.003 string.py:112(__init__)
    10000    0.003    0.000    0.003    0.000 cpminimal.py:16(method1)
    10000    0.003    0.000    0.003    0.000 cpminimal.py:19(method2)
        2    0.000    0.000    0.002    0.001 sre_parse.py:677(parse)
      7/2    0.000    0.000    0.002    0.001 sre_parse.py:301(_parse_sub)
     10/2    0.001    0.000    0.002    0.001 sre_parse.py:379(_parse)
        3    0.000    0.000    0.001    0.000 dynamic.py:103(__getattr__)
        2    0.000    0.000    0.001    0.001 sre_compile.py:478(_code)
      288    0.000    0.000    0.001    0.000 sre_parse.py:201(get)
     13/2    0.000    0.000    0.001    0.000 sre_compile.py:32(_compile)
        6    0.000    0.000    0.001    0.000 sre_compile.py:178(_compile_charset)
        6    0.000    0.000    0.001    0.000 sre_compile.py:207(_optimize_charset)
      318    0.001    0.000    0.001    0.000 sre_parse.py:182(__next)
        1    0.000    0.000    0.000    0.000 glob.py:1(<module>)
        4    0.000    0.000    0.000    0.000 sre_compile.py:258(_mk_bitmap)
        2    0.000    0.000    0.000    0.000 sre_compile.py:359(_compile_info)
        1    0.000    0.000    0.000    0.000 {map}
        3    0.000    0.000    0.000    0.000 automation.py:672(GetIDsOfNames)
        3    0.000    0.000    0.000    0.000 exception.py:32(__init__)
     15/4    0.000    0.000    0.000    0.000 sre_parse.py:140(getwidth)
       57    0.000    0.000    0.000    0.000 sre_parse.py:195(match)
       36    0.000    0.000    0.000    0.000 sre_parse.py:130(__getitem__)
      192    0.000    0.000    0.000    0.000 {method 'append' of 'list' objects}
        3    0.000    0.000    0.000    0.000 {pythoncom.GetScodeString}
        1    0.000    0.000    0.000    0.000 {open}
        4    0.000    0.000    0.000    0.000 sre_parse.py:216(isname)
        3    0.000    0.000    0.000    0.000 policy.py:285(_GetIDsOfNames_)
       15    0.000    0.000    0.000    0.000 sre_parse.py:138(append)
        3    0.000    0.000    0.000    0.000 policy.py:294(_getidsofnames_)
       22    0.000    0.000    0.000    0.000 sre_compile.py:51(fixup)
        1    0.000    0.000    0.000    0.000 {method 'close' of 'file' objects}
        1    0.000    0.000    0.000    0.000 ntpath.py:62(join)
        2    0.000    0.000    0.000    0.000 sre_parse.py:178(__init__)
        3    0.000    0.000    0.000    0.000 policy.py:305(_getdispid_)
        3    0.000    0.000    0.000    0.000 <string>:12(__init__)
        1    0.000    0.000    0.000    0.000 re.py:204(escape)
        1    0.000    0.000    0.000    0.000 dynamic.py:171(CDispatch)
        4    0.000    0.000    0.000    0.000 sre_parse.py:72(opengroup)
        2    0.000    0.000    0.000    0.000 ntpath.py:95(splitdrive)
       13    0.000    0.000    0.000    0.000 sre_parse.py:90(__init__)
       30    0.000    0.000    0.000    0.000 {min}
        2    0.000    0.000    0.000    0.000 sre_parse.py:257(_escape)
       13    0.000    0.000    0.000    0.000 {method 'get' of 'dict' objects}
        4    0.000    0.000    0.000    0.000 sre_parse.py:83(closegroup)
        2    0.000    0.000    0.000    0.000 sre_compile.py:354(_simple)
        2    0.000    0.000    0.000    0.000 {_sre.compile}
       25    0.000    0.000    0.000    0.000 sre_parse.py:210(isident)
        4    0.000    0.000    0.000    0.000 sre_compile.py:472(isstring)
       26    0.000    0.000    0.000    0.000 {_sre.getlower}
        1    0.000    0.000    0.000    0.000 {cPickle.Unpickler}
       11    0.000    0.000    0.000    0.000 sre_parse.py:126(__len__)
        1    0.000    0.000    0.000    0.000 __init__.py:523(VARIANT)
        2    0.000    0.000    0.000    0.000 {method 'join' of 'str' objects}
        1    0.000    0.000    0.000    0.000 build.py:102(DispatchItem)
        3    0.000    0.000    0.000    0.000 {method 'startswith' of 'str' objects}
        2    0.000    0.000    0.000    0.000 {time.time}
       23    0.000    0.000    0.000    0.000 {ord}
        4    0.000    0.000    0.000    0.000 {method 'remove' of 'list' objects}
        1    0.000    0.000    0.000    0.000 cpminimal.py:25(printStats)
        1    0.000    0.000    0.000    0.000 string.py:543(Formatter)
        3    0.000    0.000    0.000    0.000 {method 'lower' of 'unicode' objects}
        2    0.000    0.000    0.000    0.000 sre_parse.py:67(__init__)
        4    0.000    0.000    0.000    0.000 {method 'extend' of 'list' objects}
        1    0.000    0.000    0.000    0.000 __init__.py:420(DispatchBaseClass)
        1    0.000    0.000    0.000    0.000 string.py:102(_TemplateMetaclass)
        1    0.000    0.000    0.000    0.000 {hasattr}
        1    0.000    0.000    0.000    0.000 string.py:124(Template)
        3    0.000    0.000    0.000    0.000 dynamic.py:37(__init__)
        2    0.000    0.000    0.000    0.000 {method 'replace' of 'str' objects}
        1    0.000    0.000    0.000    0.000 string.py:85(_multimap)
        1    0.000    0.000    0.000    0.000 build.py:56(MapEntry)
        1    0.000    0.000    0.000    0.000 CLSIDToClass.py:18(<module>)
        1    0.000    0.000    0.000    0.000 __init__.py:164(__init__)
        2    0.000    0.000    0.000    0.000 sre_parse.py:134(__setitem__)
        4    0.000    0.000    0.000    0.000 {max}
        1    0.000    0.000    0.000    0.000 __init__.py:496(CoClassBaseClass)
        1    0.000    0.000    0.000    0.000 __init__.py:116(CDispatch)
        1    0.000    0.000    0.000    0.000 build.py:87(OleItem)
        1    0.000    0.000    0.000    0.000 __init__.py:161(Constants)
        6    0.000    0.000    0.000    0.000 sre_compile.py:24(_identityfunction)
        1    0.000    0.000    0.000    0.000 __init__.py:190(EventsProxy)
        1    0.000    0.000    0.000    0.000 sre_parse.py:207(seek)
        2    0.000    0.000    0.000    0.000 {method 'items' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 build.py:391(VTableItem)
        1    0.000    0.000    0.000    0.000 build.py:37(NotSupportedException)
        1    0.000    0.000    0.000    0.000 build.py:408(LazyDispatchItem)
        1    0.000    0.000    0.000    0.000 {method 'clear' of 'dict' objects}
        1    0.000    0.000    0.000    0.000 sre_parse.py:205(tell)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: cpminimaltest.py
Type: application/octet-stream
Size: 344 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-win32/attachments/20170207/8c340ff0/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cpminimal.py
Type: application/octet-stream
Size: 1124 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-win32/attachments/20170207/8c340ff0/attachment-0001.obj>


More information about the python-win32 mailing list