У меня есть декоратор, который я использую как обработчик исключений. Я хочу оптимизировать его, потому что по сравнению с простым try ... catch это примерно в 6 раз медленнее.
Код моего декоратора:
class ProcessException(object):
__slots__ = ('func', 'custom_handlers', 'exclude')
def __init__(self, custom_handlers=None):
self.func = None
self.custom_handlers: dict = custom_handlers
self.exclude = [QueueEmpty, QueueFull, TimeoutError]
def __call__(self, func):
self.func = func
return self.wrapper
def wrapper(self, *args, **kwargs):
if self.custom_handlers:
if isinstance(self.custom_handlers, property):
self.custom_handlers = self.custom_handlers.__get__(self, self.__class__)
if asyncio.iscoroutinefunction(self.func):
return self._coroutine_exception_handler(*args, **kwargs)
else:
return self._sync_exception_handler(*args, **kwargs)
async def _coroutine_exception_handler(self, *args, **kwargs):
try:
return await self.func(*args, **kwargs)
except Exception as e:
if self.custom_handlers and e.__class__ in self.custom_handlers:
return self.custom_handlers[e.__class__]()
if e.__class__ not in self.exclude:
raise e
def _sync_exception_handler(self, *args, **kwargs):
try:
return self.func(*args, **kwargs)
except Exception as e:
if self.custom_handlers and e.__class__ in self.custom_handlers:
return self.custom_handlers[e.__class__]()
if e.__class__ not in self.exclude:
raise e
В качестве теста я использовал простую функцию спопробуй ... поймай и работай с моим декоратором:
# simple function
def divide(a, b):
try:
return a // b
except ZeroDivisionError:
return 'error'
# function with decorator
@ProcessException({ZeroDivisionError: lambda: 'err'})
def divide2(a, b):
return a // b
Результат для 10000 итераций простой функции:
timeit.timeit('divide(1, 0)', number=10000, setup='from __main__ import divide')
0.010692662000110431
И функция с декоратором:
timeit.timeit('divide2(1, 0)', number=10000, setup='from __main__ import divide2')
0.053688491000002614
Помогите мне, пожалуйста, оптимизировать его и, пожалуйста, объясните, где узкое место?