<div dir="ltr"><div><div><div>Inada-san,<br><br></div>I have made a PR for typing module upstream <a href="https://github.com/python/typing/pull/383">https://github.com/python/typing/pull/383</a><br></div><div>It should reduce the memory consumption significantly (and also increase isinstance() speed).<br></div>Could you please try it with your real code base and test memory consumption (and maybe speed) as compared to master?<br><br>--<br></div>Ivan<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On 23 January 2017 at 12:25, INADA Naoki <span dir="ltr"><<a href="mailto:songofacandy@gmail.com" target="_blank">songofacandy@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Fri, Jan 20, 2017 at 8:52 PM, Ivan Levkivskyi <<a href="mailto:levkivskyi@gmail.com">levkivskyi@gmail.com</a>> wrote:<br>
</span><div><div class="h5">> On 20 January 2017 at 11:49, INADA Naoki <<a href="mailto:songofacandy@gmail.com">songofacandy@gmail.com</a>> wrote:<br>
>><br>
>> * typing may increase memory footprint, through functions<br>
>> __attributes__ and abc.<br>
>>    * Can we add option to remove or lazy evaluate __attributes__ ?<br>
><br>
><br>
> This idea already appeared few times. I proposed to introduce a flag (e.g.<br>
> -OOO) to ignore function and variable annotations in compile.c<br>
> It was decide to postpone this, but maybe we can get back to this idea.<br>
><br>
> In 3.6, typing is already (quite heavily) optimized for both speed and<br>
> space.<br>
> I remember doing an experiment comparing a memory footprint with and without<br>
> annotations, the difference was few percent.<br>
> Do you have such comparison (with and without annotations) for your app?<br>
> It would be nice to have a realistic number to estimate what would the<br>
> additional optimization flag save.<br>
><br>
> --<br>
> Ivan<br>
><br>
><br>
<br>
</div></div>Hi, Ivan.<br>
<br>
I investigated why our app has so many WeakSet today.<br>
<br>
We have dozen or hundreds of annotations like Iterable[User] or List[User].<br>
(User is one example of application's domain object.  There are<br>
hundreds of classes).<br>
<br>
On the other hand, SQLAlchemy calls isinstance(obj,<br>
collections.Iterable) many times,<br>
in [sqlalchemy.util._collections.<wbr>to_list](<a href="https://github.com/zzzeek/sqlalchemy/blob/master/lib/sqlalchemy/util/_collections.py#L795-L804" rel="noreferrer" target="_blank">https://github.com/<wbr>zzzeek/sqlalchemy/blob/master/<wbr>lib/sqlalchemy/util/_<wbr>collections.py#L795-L804</a>)<br>
method.<br>
<br>
So there are (# of iterable subclasses) weaksets for negative cache,<br>
and each weakset<br>
contains (# of column types) entries.  That's why WeakSet ate much RAM.<br>
<br>
It may be slowdown application startup too, because thousands of<br>
__subclasscheck_ is called.<br>
<br>
I gave advice to use 'List[User]' instead of List[User] to the team of<br>
the project,<br>
if the team think RAM usage or boot speed is important.<br>
<br>
FWIW, stacktrace is like this:<br>
<br>
  File "/Users/inada-n/local/py37dbg/<wbr>lib/python3.7/_weakrefset.py", line 84<br>
    self.data.add(ref(item, self._remove))<br>
  File "/Users/inada-n/local/py37dbg/<wbr>lib/python3.7/abc.py", line 233<br>
    cls._abc_negative_cache.add(<wbr>subclass)<br>
  File "/Users/inada-n/local/py37dbg/<wbr>lib/python3.7/abc.py", line 226<br>
    if issubclass(subclass, scls):<br>
  File "/Users/inada-n/local/py37dbg/<wbr>lib/python3.7/abc.py", line 226<br>
    if issubclass(subclass, scls):<br>
  File "/Users/inada-n/local/py37dbg/<wbr>lib/python3.7/abc.py", line 191<br>
    return cls.__subclasscheck__(<wbr>subclass)<br>
  File "venv/lib/python3.7/site-<wbr>packages/sqlalchemy/util/_<wbr>collections.py",<br>
line 803<br>
    or not isinstance(x, collections.Iterable):<br>
  File "venv/lib/python3.7/site-<wbr>packages/sqlalchemy/orm/<wbr>mapper.py", line 1680<br>
    columns = util.to_list(prop)<br>
  File "venv/lib/python3.7/site-<wbr>packages/sqlalchemy/orm/<wbr>mapper.py", line 1575<br>
    prop = self._property_from_column(<wbr>key, prop)<br>
  File "venv/lib/python3.7/site-<wbr>packages/sqlalchemy/orm/<wbr>mapper.py", line 1371<br>
    setparent=True)<br>
  File "venv/lib/python3.7/site-<wbr>packages/sqlalchemy/orm/<wbr>mapper.py", line 675<br>
    self._configure_properties()<<wbr>PasteEnd><br>
<br>
Regards,<br>
</blockquote></div><br></div>