-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
quadratic-time compilation in the number of 'and' or 'or' expressions #65722
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
Comments
Python's compiler has quadratic-time time behavior based on the number of "and" or "or" expressions. A profile shows that stackdepth_walk is calling itself in a stack at least 512 levels deep. (My profiler doesn't go higher than that.) I've reduced it to a simple test case. Compiling functions of the form def f(x):
x * x # Repeat N times takes linear time in the number of lines N, while functions of the form
takes quadratic time in N. Here's an example of running the attached demonstration code on a fresh build of Python from version control:
The same behavior occurs when I replace 'and' with 'or'. The same behavior also occurs under Python 2.7.2, 3.3.5, 3.4.0. (I don't have builds of 3.1 or 3.2 for testing.) However, the demonstration code shows linear time under Python 2.6.6:
I came across this problem because my code imports a large machine-generated module. It was originally written for Python 2.6, where it worked just fine. When I tried to import it under new Pythons, the import appeared to hang, and I killed it after a minute or so. As a work-around, I have re-written the code generator to use chained if-statements instead of the short-circuit and operator. |
Andrew, have you tried to bisect the Mercurial repository to find where the regression was introduced? |
Live and learn. I did my first bisect today. The first bad revision is: I confirmed that the parent did not have the problem. If you want me to diagnose this further, then I'll need some hints on what to do next. |
You're right, CPU time is burnt by stackdepth_walk(). Still, of course, stackdepth_walk() should not blow up when computing a large stack size, but fixing the opcode's stack effect in compile.c seems to fix the issue anyway. |
Here is a patch. |
Updated patch adding some tests. |
The patch looks like the correct solution. That said, I'm more impressed that you were able to test it so cleanly :-) |
New changeset cd62cc331572 by Antoine Pitrou in branch '3.4': New changeset e61462e18112 by Antoine Pitrou in branch 'default': New changeset 49588a510ed4 by Antoine Pitrou in branch '2.7': |
This should be fixed now! |
Note: 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: