[Python-Dev] Investigating Python memory footprint of one real Web application
INADA Naoki
songofacandy at gmail.com
Mon Jan 23 06:25:40 EST 2017
On Fri, Jan 20, 2017 at 8:52 PM, Ivan Levkivskyi <levkivskyi at gmail.com> wrote:
> On 20 January 2017 at 11:49, INADA Naoki <songofacandy at gmail.com> wrote:
>>
>> * typing may increase memory footprint, through functions
>> __attributes__ and abc.
>> * Can we add option to remove or lazy evaluate __attributes__ ?
>
>
> This idea already appeared few times. I proposed to introduce a flag (e.g.
> -OOO) to ignore function and variable annotations in compile.c
> It was decide to postpone this, but maybe we can get back to this idea.
>
> In 3.6, typing is already (quite heavily) optimized for both speed and
> space.
> I remember doing an experiment comparing a memory footprint with and without
> annotations, the difference was few percent.
> Do you have such comparison (with and without annotations) for your app?
> It would be nice to have a realistic number to estimate what would the
> additional optimization flag save.
>
> --
> Ivan
>
>
Hi, Ivan.
I investigated why our app has so many WeakSet today.
We have dozen or hundreds of annotations like Iterable[User] or List[User].
(User is one example of application's domain object. There are
hundreds of classes).
On the other hand, SQLAlchemy calls isinstance(obj,
collections.Iterable) many times,
in [sqlalchemy.util._collections.to_list](https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/util/_collections.py#L795-L804)
method.
So there are (# of iterable subclasses) weaksets for negative cache,
and each weakset
contains (# of column types) entries. That's why WeakSet ate much RAM.
It may be slowdown application startup too, because thousands of
__subclasscheck_ is called.
I gave advice to use 'List[User]' instead of List[User] to the team of
the project,
if the team think RAM usage or boot speed is important.
FWIW, stacktrace is like this:
File "/Users/inada-n/local/py37dbg/lib/python3.7/_weakrefset.py", line 84
self.data.add(ref(item, self._remove))
File "/Users/inada-n/local/py37dbg/lib/python3.7/abc.py", line 233
cls._abc_negative_cache.add(subclass)
File "/Users/inada-n/local/py37dbg/lib/python3.7/abc.py", line 226
if issubclass(subclass, scls):
File "/Users/inada-n/local/py37dbg/lib/python3.7/abc.py", line 226
if issubclass(subclass, scls):
File "/Users/inada-n/local/py37dbg/lib/python3.7/abc.py", line 191
return cls.__subclasscheck__(subclass)
File "venv/lib/python3.7/site-packages/sqlalchemy/util/_collections.py",
line 803
or not isinstance(x, collections.Iterable):
File "venv/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 1680
columns = util.to_list(prop)
File "venv/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 1575
prop = self._property_from_column(key, prop)
File "venv/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 1371
setparent=True)
File "venv/lib/python3.7/site-packages/sqlalchemy/orm/mapper.py", line 675
self._configure_properties()<PasteEnd>
Regards,
More information about the Python-Dev
mailing list