<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">I’m new to this issue, but curious: could the long-running server mitigate lazy loading problems simply by explicitly importing the deferred modules, e.g. at the top of __main__.py? It would require some performance tracing or other analysis to figure out what needed to be imported, but this might be a very easy way to win back response times for demanding applications. Conversely, small scripts currently have no recourse.<div class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Oct 2, 2017, at 7:10 AM, INADA Naoki <<a href="mailto:songofacandy@gmail.com" class="">songofacandy@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi.<div class=""><br class=""></div><div class="">My company is using Python for web service.</div><div class="">So I understand what you're worrying.</div><div class="">I'm against fine grained, massive lazy loading too.</div><div class=""><br class=""></div><div class="">But I think we're careful enough for lazy importing.</div><div class=""><br class=""></div><div class=""><a href="https://github.com/python/cpython/pull/3849" class="">https://github.com/python/cpython/pull/3849</a><br class=""></div><div class="">In this PR, I stop using textwrap entirely, instead of lazy import.</div><div class=""><br class=""></div><div class=""><a href="https://github.com/python/cpython/pull/3796" class="">https://github.com/python/cpython/pull/3796</a><br class=""></div><div class="">In this PR, lazy loading only happens when uuid1 is used.</div><div class="">But uuid1 is very uncommon for nowdays.</div><div class=""><br class=""></div><div class=""><a href="https://github.com/python/cpython/pull/3757" class="">https://github.com/python/cpython/pull/3757</a><br class=""></div><div class="">In this PR, singledispatch is lazy loading types and weakref.</div><div class="">But singledispatch is used as decorator.</div><div class="">So if web application uses singledispatch, it's loaded before preforking.</div><div class=""><br class=""></div><div class=""><a href="https://github.com/python/cpython/pull/1269" class="">https://github.com/python/cpython/pull/1269</a><br class=""></div><div class="">In this PR, there are some lazy imports.</div><div class="">But the number of lazy imports seems small enough.</div><div class=""><br class=""></div><div class="">I don't think we're going to too aggressive.<br class=""></div><div class=""><br class=""></div><div class="">In case of regular expression, we're about starting discussion.</div><div class="">No real changes are made yet.</div><div class=""><br class=""></div><div class="">For example, tokenize.py has large regular expressions.</div><div class="">But most of web application uses only one of them: linecache.py uses</div><div class="">tokenize.open(), and it uses regular expression for encoding cookie.</div><div class="">(Note that traceback is using linecache.  It's very commonly imported.)</div><div class=""><br class=""></div><div class="">So 90% of time and memory for importing tokenize is just a waste not</div><div class="">only CLI application, but also web applications.</div><div class="">I have not create PR to lazy importing linecache or tokenize, because</div><div class="">I'm worrying about "import them at first traceback".</div><div class=""><br class=""></div><div class="">I feel Go's habit helps in some cases; "A little copying is better than a little dependency."</div><div class="">(<a href="https://go-proverbs.github.io/" class="">https://go-proverbs.github.io/</a> )</div><div class="">Maybe, copying `tokenize.open()` into linecache is better than lazy loading tokenize.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Anyway, I completely agree with you; we should careful enough about lazy (importing | compiling).</div><div class=""><br class=""></div><div class="">Regards,</div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Mon, Oct 2, 2017 at 6:47 PM Christian Heimes <<a href="mailto:christian@python.org" class="">christian@python.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello python-dev,<br class="">
<br class="">
it's great to see that so many developers are working on speeding up<br class="">
Python's startup. The improvements are going to make Python more<br class="">
suitable for command line scripts. However I'm worried that some<br class="">
approaches are going to make other use cases slower and less efficient.<br class="">
I'm talking about downsides of lazy initialization and deferred imports.<br class="">
<br class="">
<br class="">
For short running command line scripts, lazy initialization of regular<br class="">
expressions and deferred import of rarely used modules can greatly<br class="">
reduce startup time and reduce memory usage.<br class="">
<br class="">
<br class="">
For long running processes, deferring imports and initialization can be<br class="">
a huge performance problem. A typical server application should<br class="">
initialize as much as possible at startup and then signal its partners<br class="">
that it is ready to serve requests. A deferred import of a module is<br class="">
going to slow down the first request that happens to require the module.<br class="">
This is unacceptable for some applications, e.g. Raymond's example of<br class="">
speed trading.<br class="">
<br class="">
It's even worse for forking servers. A forking HTTP server handles each<br class="">
request in a forked child. Each child process has to compile a lazy<br class="">
regular expression or important a deferred module over and over.<br class="">
uWSGI's emperor / vassal mode us a pre-fork model with multiple server<br class="">
processes to efficiently share memory with copy-on-write semantics. Lazy<br class="">
imports will make the approach less efficient and slow down forking of<br class="">
new vassals.<br class="">
<br class="">
<br class="">
TL;DR please refrain from moving imports into functions or implementing<br class="">
lazy modes, until we have figured out how to satisfy requirements of<br class="">
both scripts and long running services. We probably need a PEP...<br class="">
<br class="">
Christian<br class="">
_______________________________________________<br class="">
Python-Dev mailing list<br class="">
<a href="mailto:Python-Dev@python.org" target="_blank" class="">Python-Dev@python.org</a><br class="">
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank" class="">https://mail.python.org/mailman/listinfo/python-dev</a><br class="">
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/songofacandy%40gmail.com" rel="noreferrer" target="_blank" class="">https://mail.python.org/mailman/options/python-dev/songofacandy%40gmail.com</a><br class="">
</blockquote></div><div dir="ltr" class="">-- <br class=""></div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr" class="">Inada Naoki <<a href="mailto:songofacandy@gmail.com" class="">songofacandy@gmail.com</a>></div></div>
_______________________________________________<br class="">Python-Dev mailing list<br class=""><a href="mailto:Python-Dev@python.org" class="">Python-Dev@python.org</a><br class="">https://mail.python.org/mailman/listinfo/python-dev<br class="">Unsubscribe: https://mail.python.org/mailman/options/python-dev/gwk.lists%40gmail.com<br class=""></div></blockquote></div><br class=""></div></body></html>