New submission from Federico Caselli <cfederic...@gmail.com>:
The implementation of singledispatchmethod is significantly slower (~4x) than the normal singledispatch version Using timeit to test this example case: from functools import singledispatch, singledispatchmethod import timeit class Test: @singledispatchmethod def go(self, item, arg): print('general') @go.register def _(self, item:int, arg): return item + arg @singledispatch def go(item, arg): print('general') @go.register def _(item:int, arg): return item + arg print(timeit.timeit('t.go(1, 1)', globals={'t': Test()})) print(timeit.timeit('go(1, 1)', globals={'go': go})) Prints on my system. 3.118346 0.713173 Looking at the singledispatchmethod implementation I believe that most of the difference is because a new function is generated every time the method is called. Maybe an implementation similar to cached_property could be used if the class has __dict__ attribute? Trying this simple patch diff --git a/Lib/functools.py b/Lib/functools.py index 5cab497..e42f485 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -900,6 +900,7 @@ class singledispatchmethod: self.dispatcher = singledispatch(func) self.func = func + self.attrname = None def register(self, cls, method=None): """generic_method.register(cls, func) -> func @@ -908,6 +909,10 @@ class singledispatchmethod: """ return self.dispatcher.register(cls, func=method) + def __set_name__(self, owner, name): + if self.attrname is None: + self.attrname = name + def __get__(self, obj, cls=None): def _method(*args, **kwargs): method = self.dispatcher.dispatch(args[0].__class__) @@ -916,6 +921,7 @@ class singledispatchmethod: _method.__isabstractmethod__ = self.__isabstractmethod__ _method.register = self.register update_wrapper(_method, self.func) + obj.__dict__[self.attrname] = _method return _method @property improves the performance noticeably 0.9720976 0.7269078 ---------- components: Library (Lib) messages: 371594 nosy: CaselIT priority: normal severity: normal status: open title: singledispatchmethod significantly slower than singledispatch type: performance versions: Python 3.8 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue40988> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com