mihnita / ansi-econsole

Eclipse plugin that understands ANSI escape sequences to color the Eclipse console output.
http://www.mihai-nita.net/java/
Other
90 stars 25 forks source link

Console hang issue and slow performance on Windows #66

Open martinlippert opened 2 years ago

martinlippert commented 2 years ago

There is a report being filed on the STS4 issue tracker that complains about slow redraw performance in the console and it seems to be related to the ANSI console. Here is the comment comparing plain Eclipse with and without the ANSI Console plugin:

https://github.com/spring-projects/sts4/issues/689#issuecomment-940587858

mihnita commented 2 years ago

This looks like a duplication of https://github.com/mihnita/ansi-econsole/issues/27

At the time I think I managed to point the problem to Eclipse itself, which performs miserably on Windows. I've manged to improve the performance somewhat by using caching. But then 2020-12 came and undid a lot of my work :-(

See from this commend down: https://github.com/mihnita/ansi-econsole/issues/27#issuecomment-640113665

At this point all I can do is open an issue with Eclipse.

shankarwww commented 2 years ago

STS 4.14.0 is released and issue still remains the same. When can we expect a fix ?

martinlippert commented 2 years ago

Seems like this is caused by https://bugs.eclipse.org/bugs/show_bug.cgi?id=579406, which got fixed in SWT and will be released as part of Eclipse 2022-06 (expected to appear in June 2022).

mihnita commented 2 years ago

which got fixed in SWT and will be released as part of Eclipse 2022-06

That would be really nice!

shankarwww commented 2 years ago

Seems like this is caused by https://bugs.eclipse.org/bugs/show_bug.cgi?id=579406, which got fixed in SWT and will be released as part of Eclipse 2022-06 (expected to appear in June 2022).

m waiting for this release :)

jukzi commented 2 years ago

very useful plugin, but unfortunately eclipse freezes when running

public static void main(String[] args) {
        for (int i=1;i<300000;i++) {
            System.out.println("\u001b[30mblack\u001b[31mred "+i);
        }
}

while

public static void main(String[] args) {
        for (int i=1;i<300000;i++) {
            System.out.println("     black     red "+i);
        }
}

runs very fast.

i sampled the frozen state a bit: image The problem is that there is too much updates as soon as the trim() detects that the console got too big

i do not know if it's also an issue that the trim might happen just within a escape sequence - which is then also rendered wrong: image

mihnita commented 2 years ago

Thanks jukzi Also thank you for spending the time to profile it, very useful, saved me some time.

I confirm, I can reproduce it. Some preliminary digging: as it is also visible from your trace, the time is spent in org.eclipse.jface.text.DefaultPositionUpdater.update()

But DefaultPositionUpdater is not mine, it is Eclipse. I don't know what it does that takes soo long, and if I can replace it.

The performance drops dramatically when the console buffer runs out. Then everything is "shifted", the first lines of output are deleted, and (I think) the offsets of all positions are adjusted.

I've tried commenting out the call of defaultPositionUpdater.update(event) in AnsiConsoleStyleListener.update And the performance improves dramatically. But if the console buffer is too small then the wrong text is colored, the escapes start showing, etc. Meaning that the offsets of the attribute changes are wrong.

If I increase the console buffer, or I uncheck "Limit console output", then all is good, both performance, and colors. But of course that is not a good solution.

The only idea I have right now is to see if I can understand what DefaultPositionUpdater does, and see if I can do it myself, but a lot faster.

Thank you, M

mihnita commented 2 years ago

Yes, I think you say the same thing with "The problem is that there is too much updates as soon as the trim() detects that the console got too big"

True. There is no performance hit for non-colored text because only colored text creates a list of positions associated with the document.

When the first lines in the buffer get deleted, then all the positions (of style attributes) also need to be deleted. The positions are is an ArrayList, and the deletion happens from the beginning, because the algorithm iterate the positions, and for each one asks if it needs to be deleted, then deletes it. So technically for each deletion the whole array is copied one element over.

It is a call to System.arraycopy, so it is fast. But if it happens hundreds of thousands of times, on a big (array)list, it adds up.

With some work it can probably be optimized to delete only once. But that is in Eclipse. There is not much I can do, unless I do the fixes in Eclipse, and contribute it.

Not 100% excluded, but until September I will be quite busy.

But for now the label I applied to this bug (3rd Party?) seems still valid.

For now, your real life use cases produce this kind of output, you can try unchecking "Limit console output" I've tried it, and the result is fast, almost as fast as non-colored text (I can't notice a difference without measuring) But you pay with memory for speed.

jukzi commented 2 years ago

it's not a real world use case. i just wondered why new RuntimeException("" + i).printStackTrace(); also does coloring but does not have that speed problem. feels like coloring the stacktrace is done after the trim.

shankarwww commented 2 years ago

@mihnita I have already unchecked "Limit console output" but the issue remains same for me