Skip to content
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

Jediterm performance #294

Open
borissmidt opened this issue Jan 12, 2025 · 0 comments
Open

Jediterm performance #294

borissmidt opened this issue Jan 12, 2025 · 0 comments

Comments

@borissmidt
Copy link

Dear,

I wondered why the intellij terminal was slow and did some simple profiling by running a cat in a loop to just have a lot of characters printed to the terminal.

A great amout of impact seems to come from the state that is tracked on each read:
https://github.com/JetBrains/jediterm/blame/70b67201b180440814150d498edf55ab87caf075/JediTerm/src/main/kotlin/com/jediterm/app/JediTermMain.kt#L118-L129

I tried to make it faster by passing a single string builder in tot 'collect' the result that didn't really help.
So i just commented it out and suddenly the terminal was 2x faster as a result. But i don't see it being used in intellij itself so this can be ignored.

Another change i've found that makes quite a lot of impact is to increase the read buffer size to 4096 and to read a bigger chunk in one go:

in DataStreamIteratingEmulator

  public void next() throws IOException {
    try {
      String b = myDataStream.readNonControlCharacters(4096);
      if (!b.isEmpty()) {
        myTerminal.writeCharacters(b);
      } else {
        processChar(myDataStream.getChar(), myTerminal);
      }
    }
    catch (TerminalDataStream.EOF e) {
      myEof = true;
    }
  }

With a debugger i found out that this wasn't working that well unless i update the control character check to ignore tabs and end line characters otherwise the buffer is almost completely empty this would also trigger the process hyperlinks less which is quite expensive because of the regex usage.

  public static String getNonControlCharacters(int maxChars, char[] buf, int offset, int charsLength) {
    int len = Math.min(maxChars, charsLength);

    final int origLen = len;
    char tmp;
    while (len > 0) {
      tmp = buf[offset++];
      if (0x20 <= tmp && tmp != '\t' && tmp != '\n' && tmp != '\r') { //stop when we reach control chars
        len--;
        continue;
      }
      offset--;
      break;
    }

    int length = origLen - len;

    return new String(buf, offset - length, length);
  }

I'm not sure how much impact these changes would have inside intellij itself since there seem to be quite a lot of hooks where many coroutines are started. So probably some performance can be won there as well.

It really is a very simple test so maybe it can be best to add this to the 'performance' benchmarks for the future.
Essentially i run a 1000 cats of a a rather big file.

for i in {0..1000}; do
 cat ~/projects/long-md-file.md
done

As a comparison with my changes it can run in 5s while the main branch terminal does it in 46s.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant