-
-
Notifications
You must be signed in to change notification settings - Fork 30.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add -X option to show import time #75596
Comments
I used my local patch to profile import time. I think it's useful for ./python -Ximportprofile -c 'import traceback'
|
What does the "[us]" mean? |
It means μs (micro seconds), in ASCII. On 2017年9月20日(水) 3:35 Brett Cannon <report@bugs.python.org> wrote:
-- |
If this proposition be accepted I would want to see not only cumulated times, but also pure times, without time of nested imports. I guess this feature doesn't work correctly with threading. |
Ah, OK. Then I wouldn't put it in square brackets as it seems to suggest it's somehow disconnected from the number. |
It can be calculated by script.
Yes, it should be documented. |
Actually it is easy. You need just one global integer accumulator and a local variable for keeping a temporary copy of it. |
You're right! I updated my pull request. |
Guido, is this something you want? Historically, we've shown a lot of restraint when it comes to adding command-line options. Also, I'm not sure we want to induce people to start moving their imports inside function calls. Just because we sometimes adopt constipated programming practices in the standard library doesn't mean we think everyone should do it. (This is doubly true because sometimes the savings is a false savings if the import eventually occurs downstream and because there is currently work being done on lazy imports that would make the technique irrelevant). |
I think it is useful given how much debate there has been around startup time in various contexts (not just pure interpreter startup time but also startup time when using specific libraries, packages or applications).
But this is hardly a new command-line option; -X already exists. I think it's reasonable to add it here.
That's a big leap from collecting the data to suggesting a specific solution. I don't think that making it harder to get the data really is the right approach to discouraging a debatable practice (plus, there are many situations where the practice *is* useful -- just as there are many situations where it's counterproductive). Consenting adults. |
Naoki, is it possible to separate out how much of this is I/O vs CPU time? If the I/O dominates, optimizations tend toward zipimports, faster drives, disk caching etc. If the CPU time is dominant, different techniques are used (lazy evaluation, splitting-out parts of a package, etc). |
I don't have any good idea for it. I usually run On Linux, $ strace -c python -c 'import asyncio'
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- 0.00 0.000000 0 244 read $ /usr/bin/time python -c 'import asyncio'
0.12user 0.00system 0:00.13elapsed 98%CPU (0avgtext+0avgdata 17004maxresident)k
0inputs+0outputs (0major+2613minor)pagefaults 0swaps |
how can I make it more machine readable? On 2017年9月25日(月) 19:39 Christian Heimes <report@bugs.python.org> wrote:
-- |
The output in PR 3765 partially duplicates the output of the -v option. |
Right. But the idea is to be able to use "grep 'import time:'" to only extract importtime logs. "-v" logs different kind of informations. |
Related: https://bugs.python.org/issue31574 |
Thank you Naoki for this nice enhancement! Tooling always help to take smart decisions on optimizations. |
This is pretty useless on Windows because you are using a clock with 15-16 milli (not micro) second resolution on Windows. Before Victor introduced time.perf_counter, with decent behavior on all systems, timeit used different time module functions on Windows and *nix because the two different functions had such different behavior on the two systems. I believe it used time.clock on Windows (1 second resolution of *nix?) and time.time otherwise (.016 sec resolution on Windows). Time.monotonic seems to be based on time.time as it has the same low resolution on Windows. Run something like for i in range(1000): time.monotonic() and you will see identical times except for 1 or 2 jumps of .016. So the C equivalent or time.clock or time.perf_counter is needed on Windows. Victor can advise as he knows this better than me. An example of nearly useless output, with 15-16 millisecond resolution. f:\dev\3x>python -X importtime -c "import idlelib.pyshell" |
Lines 80 to 112 in 27c623c
time module has perf_counter implementation based on QueryPerformanceCounter(). Could we change PyTime_GetMonotonicClock implementation to use it on Windows? I don't want to so much code to import.c. But if pytime.c has nice clock |
No. See the PEP-418 for the rationale. But we could add a _PyTime_GetPerfCounter() to Python/pytime.c. |
Why global _PyTime_GetWinPerfCounterWithInfo() is needed at all? It seems to me that _PyTime_GetPerfCounterWithInfo() can be used instead. Smaller API is better. _PyTime_GetPerfCounter() is a simple wrapper around _PyTime_GetPerfCounterWithInfo() and is used only in one place. Getting rid of it will simplify C API too. |
Does it worth enough? |
I don't care much of performance. For the consistency with other environment variables, I like to only read the environment variable once ("at startup"), and not do it each time. |
Xoptions is not environment variable. Some modules are imported before xoptions are parsed. |
I like this a lot and while the issue is still open, I'm piggybacking my PR 4240 on this one. I have a use case for enabling this feature via environment variable, so PR 4240 adds PYTHONPROFILEIMPORTTIME which also enables this feature. We build our tools using pex, which hardcodes the shebang at the top of the zip file. This isn't easily changed, and clearly we wouldn't want to enable -X importtime everywhere. When we have startup performance issues, I want to be able to tell people (or set it up in our CI) to set the environment variable and collect the data for analysis. This is much easier than tweaking the shebang or invoking the zip with an explicit command. Also, there are potential gotchas with loading too much up on the shebang line (IIRC, there are line length limits and/or multiple option limits for shebangs, e.g. if we wanted to have both -I and -X). I haven't fixed the initialization check problem that serhiy.storchaka points out, since that's addressed by PR 4138. But maybe I should fold that change into mine. |
When adding environment variable option, it should be documented in |
On Nov 2, 2017, at 22:50, INADA Naoki report@bugs.python.org wrote:
I thought about that, but the problem is that none of the -X options are documented in the —help output. So do we only document the ones (e.g. importtime) that have an environment variable version, or do we now have to document them all? I opted to document PYTHONPROFILEIMPORTTIME only in the cmdline documentation. |
I agree. The main value of my patch is handling possible (but very unlike) errors. Implementing negative value caching adds not many lines to the existing code and additional error handling. But now, after adding the environment variable, do we still need the -X option? From a user side I don't see much difference between specifying an option and an environment variable, but the code for handling the environment variable is much simpler. |
On Nov 3, 2017, at 11:05, Serhiy Storchaka <report@bugs.python.org> wrote:
It’s a good question. I guess in the limited amount of time I’ve used the feature so far, I find it kind of nice to be able to type I suppose I’m -0 on removing the -X option, and +0 on adding the negative cache. |
It does not work on Windows. C:\Users\Terry>PYTHONPROFILEIMPORTTIME=x python Does it set the EV for the entire session (which one likely would not want), or just the one command (which has no Windows equivalent that I know of)? Please leave the easily remembered and typed option. |
Note that with environment variable you get more information. $ ./python -X importtime -c pass
import time: self [us] | cumulative | imported package
import time: 88 | 88 | _codecs
import time: 789 | 876 | codecs
import time: 602 | 602 | encodings.aliases
import time: 809 | 2287 | encodings
...
$ PYTHONPROFILEIMPORTTIME=1 ./python -c pass
import time: self [us] | cumulative | imported package
import time: 3133 | 3133 | _frozen_importlib_external
import time: 371 | 371 | zipimport
import time: 327 | 327 | _codecs
import time: 2656 | 2982 | codecs
import time: 1821 | 1821 | encodings.aliases
import time: 2604 | 7406 | encodings
... |
On Windows you can create a 2-line bat-file that sets the environment variable and runs Python. |
On Nov 3, 2017, at 14:41, Serhiy Storchaka <report@bugs.python.org> wrote:
Fun! |
On Nov 3, 2017, at 14:23, Terry J. Reedy <report@bugs.python.org> wrote:
On *nix, this sets the environment variable for just this process. |
I'm +1 to remove -X option. |
One benefit (or drawback, depending on how you see it) of the -X option is that it wouldn't propagate to child processes spawned by multiprocessing. See _args_from_interpreter_flags() in Lib/subprocess.py. More generally, the idea that we should remove a command line option because there's an environment variable sounds dubious to me. Should we do the same for all command-line options? The faulthandler module can be enabled either using the The only serious reason I can imagine would be that the -X option has a significant maintenance cost. |
(and Terry is right that environment variables can be significantly more annoying on Windows) |
Okay, given the non-propagation and Windows issues. I'm -1 on removing -X, +1 on fixing the negative cache. |
For timing package import time, such as for idlelib.pyshell, rather than bare python startup time, the extra information is just a bit more noise to ignore. The importtime output is sent to stderr. Should this be documented? It is important because displaying results immediately on command prompt rather than redirecting to a file adds about .07 seconds to the total time reported for pyshell, whether I use debug or normal binaries. The relative variation between repeated runs (about 1%) also seems less with redirection to a file. |
On Nov 4, 2017, at 14:29, Terry J. Reedy <report@bugs.python.org> wrote:
Yes. :) |
I think there is nothing left to do for this issue, so I'm closing it. |
FYI I'm working on the Py_Main() function in bpo-32030. My latest PR (PR 4412) moves the code to parse -X importtime and PYTHONPROFILEIMPORTTIME into Py_Main(), to group all functions parsing the command line arguments and environment variables. With this change, the "importtime" option is now checked before the very first "Python" function call. The new code doesn't use the sys module anymore to parse -X options, and so break the dependency between "importtime", the import machinery and the sys module. |
I just updated tuna [1] to support import time profiles as well.
and use with
See screenshot for example output. Cheers, |
-X importtime
option. #3490-X importtime
option #3765Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: