-
-
Notifications
You must be signed in to change notification settings - Fork 161
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
Loops may not collect garbage, leading to very slow execution #2123
Comments
I'm on 5a67993f |
Hm thanks for the report! I have repro'd this
Let me see what's happening ... first hunch: maybe |
Gah, so yeah my hunch was right, this is a GC bug. If we do 3 iterations of the last loop, the GC spends 3+ seconds. If we do 4, it spends 4+ seconds I am not sure why at the moment, but it is a bug
|
The command was
The weird thing is that "num live" is small, which means the GC should be working correctly? Or maybe it is growing to take a huge amount of memory, and then it's all freed? So yeah the first thing to look at would be a memory leak ... possibly triggered by the Yes I think so |
OK, it does look like some kind of memory leak
So basically the GC is thrashing on the internal data structures for 200,000 lines .... going deeper ... |
This is bug #2123. Unrelated: [spec/ysh-builtin-eval] Nicer example
This resolves issue #2123. The 'filter' loop would evaluate expressions, and allocate, without every hitting a GC point. To break out of a loop or recursion, you will need 'if' or 'case'. So I believe this should work everywhere, just as it does the test/bug-2123.* repro. I'm not quite sure why the bug depended on get() NOT having a default arg though. Could look into that more.
Related to issue #2123. Because control flow raises C++ exceptions, we can skip a _LeafTick() after, which would lead to the same perf bug: if (true) { continue # exception, interpreter doesn't reach the end of 'if' }
Thank you for the report, this is fixed! http://op.oilshell.org/uuu/github-jobs/8263/ http://op.oilshell.org/uuu/github-jobs/8263/cpp-tarball.wwz/_release/oils-for-unix.tar The problem was that in the It actually was not a memory leak -- it was building up a huge heap with the 100_000 line computation, and then GC'ing it all at the end After that, I think there was less locality in all subsequence GC's! They went from 0.2 ms to ~30ms |
Using the test case from issue #2123
Also, I noticed some places where we are allocating a lot in a loop, which is low hanging fruit for speeding up the interpreter. I checked in a change to For the near future, we're focused on semantics more than speed But there is plenty left to optimize, and I appreciate perf bugs like this one! |
get()
function without a default value can cause a performance regression
I tried unsuccessfully to boil this down to a simpler reproducible example. Something about the interplay of
get
without a default value in thefilter
procedure appears to cause the issue. Sample code for reproduction:Output on my machine:
The text was updated successfully, but these errors were encountered: