You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I liked AttrDict. Then AttrDict was too slow. I liked Bunch. Then Bunch was too slow. These two libraries ended up consuming 1/2 and 1/3 of my request time when using them frequently, for what I had assumed was a very simple use-case. The main problem comes from two things 1) Bunch inherits from dict, so it brings along the entire dict implementation, which isn't always necessary(rarely is in fact). 2)bunchify aggressively goes through an entire nested dictionary, and puts copies of Bunch everywhere. This results in attributes that may never get called, getting implanted with the Bunch object.
Speeding this up proved to not take a lot of code. Check out this gist from @mmerickel, which I've copied below. It uses a light-weight DictProxy object to mediate access to the object, and it also lazy-loads each attribute. This decreased the amount of time that my app spend "Bunching" objects to relatively nothing, from 1/3 of my request time using Bunch master.
classDictProxy(object):
""" A proxy for a dictionary that allows attribute access to underlying keys. You may pass a custom ``wrapper`` to override the logic for wrapping various custom types. """def__init__(self, obj, wrapper=wrap):
self.obj=objdef__getitem__(self, key):
returnself.wrapper(self.obj[key])
def__getattr__(self, key):
try:
returnself.wrapper(getattr(self.obj, key))
exceptAttributeError:
try:
returnself[key]
exceptKeyError:
raiseAttributeError(key)
# you probably also want to proxy important list properties along like# items(), iteritems() and __len__classListProxy(object):
""" A proxy for a list that allows for wrapping items. You may pass a custom ``wrapper`` to override the logic for wrapping various custom types. """def__init__(self, obj, wrapper=wrap):
self.obj=objdef__getitem__(self, key):
returnself.wrapper(self.obj[key])
# you probably also want to proxy important list properties along like# __iter__ and __len__defwrap(value):
""" The top-level API for wrapping an arbitrary object. This only works for ``dict``, ``list`` and ``tuple`` types. If you want to wrap other types you may write your own wrap and pass ``wrapper=`` to ``DictProxy`` and ``ListProxy``. """ifisinstance(value, dict):
returnDictProxy(value)
ifisinstance(value, (tuple, list)):
returnListProxy(value)
returnvalue
The text was updated successfully, but these errors were encountered:
I think performance will always be sub-par for any convenience datatype. It will simply be better as a dict (or a list of tuples, depending). Performance improvements are always encouraged, but perf isn't a priority unless it makes the library unusable for an important use-case.
You raise a good point though: there's no test showing relative performance. We should add that.
dsc
changed the title
Bunch is Slow
Bunch is Slow — Add test for relative performance
Oct 19, 2024
I liked AttrDict. Then AttrDict was too slow. I liked Bunch. Then Bunch was too slow. These two libraries ended up consuming 1/2 and 1/3 of my request time when using them frequently, for what I had assumed was a very simple use-case. The main problem comes from two things 1) Bunch inherits from
dict
, so it brings along the entiredict
implementation, which isn't always necessary(rarely is in fact). 2)bunchify
aggressively goes through an entire nested dictionary, and puts copies of Bunch everywhere. This results in attributes that may never get called, getting implanted with the Bunch object.Speeding this up proved to not take a lot of code. Check out this gist from @mmerickel, which I've copied below. It uses a light-weight DictProxy object to mediate access to the object, and it also lazy-loads each attribute. This decreased the amount of time that my app spend "Bunching" objects to relatively nothing, from 1/3 of my request time using Bunch master.
The text was updated successfully, but these errors were encountered: