Hi Mark, I found some time to debug and profile my issue a little bit more. In my scenario I call a COM method which returns a list of 14195 integers plus the amount of the found objects.
If I profile that call I get the following: ncalls tottime percall cumtime percall filename:lineno(function) ... 1 0.000 0.000 0.025 0.025 __init__.py:572(_ApplyTypes_) 1 0.000 0.000 0.007 0.007 __init__.py:603(_get_good_object_) 14195 0.001 0.000 0.001 0.000 __init__.py:608(_get_good_single_object_) 14198/1 0.005 0.000 0.007 0.007 __init__.py:614(_get_good_object_) ... So _get_good_object_ is called ~14200 times. If I do that in a loop 100x, I get an execution time of ~3.3s If I change the code in the _ApplyTypes_ function to: def _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, resultCLSID, *args): return self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args) # return self._get_good_object_( # self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args), # user, # resultCLSID, # ) that is, avoiding the _get_good_object_() calls, the execution time is ~1.6s for 100 iterations. Which is ~50% of the original time. The result is the same, in this case. Do you have any thoughts on this? Best regards, Sven Am Mi., 17. Apr. 2024 um 17:19 Uhr schrieb Mark Hammond < skippy.hamm...@gmail.com>: > I'm mildly surprised by that - a profiler might show some low-hanging > fruit, and/or might show different characteristics when many more functions > are used. However, the primary reason for EnsureDispatch is for better > support of the object model - there's far more context available and this > less chance of upsetting some COM objects - eg, when `foo.bar` is seen, > EnsureDispatch knows for sure that `bar` is a method, but dynamic dispatch > doesn't know if the resulting object is going to be called or not. > > HTH, > > Mark > On 2024-04-17 2:07 a.m., Sven Bardos via python-win32 wrote: > > Hi, > > shouldn't be EnsureDispatch be faster than Dispatch once the code > generation is done? > > I've measured it by calling 6000 COM calls like this: > > dirpath = Path('C:/Users/sbardos/AppData/Local/Temp/gen_py/3.10/') > if dirpath.exists() and dirpath.is_dir(): > shutil.rmtree(dirpath) > > app = Dispatch("CT.Application") > job = app.CreateJobObject() > > start = timer() > > for i in range(2000): > cnt, devIds = job.GetAllDeviceIds() > cnt, sheetIds = job.GetSheetIds() > dev = job.CreateDeviceObject() > > end = timer() > print(f"Time ellapsed (late): {end - start}s") > and the ensure Dispatch version: > app = EnsureDispatch("CT.Application") > job = app.CreateJobObject() > start = timer() > for i in range(2000): > cnt, devIds = job.GetAllDeviceIds(None) > cnt, sheetIds = job.GetSheetIds(None) > dev = job.CreateDeviceObject() > end = timer() > print(f"Time ellapsed (early): {end - start}s") > EnsureDispatch is a little bit slower ~4.2s compared to ~4.0s. > If I don't get a performance boost with EnsureDispatch, is there even a > point using it? > > Thanks, > Sven > > _______________________________________________ > python-win32 mailing > listpython-win32@python.orghttps://mail.python.org/mailman/listinfo/python-win32 > >
_______________________________________________ python-win32 mailing list python-win32@python.org https://mail.python.org/mailman/listinfo/python-win32