1
0
mirror of https://github.com/arduino/Arduino.git synced 2025-02-21 15:54:39 +01:00

Improve performance on serial monitor 'Show timestamp'

This patch dramatically reduce pressure on heap memory:

- use a StringTokenizer instead of the very slow String.split(...)
  method to decode newlines. This avoid allocation/deallocation of
  big strings array and use of regexp.
- pre allocate as many object as possible to avoid new allocation
  while streaming data.
- the "timestamp" string is calculated only once per iteration.
- use StringBuilder instead of inline temporary strings (that are,
  again, allocated and deallocated on each iteration)
This commit is contained in:
Cristian Maglie 2018-08-22 14:26:45 +02:00 committed by Cristian Maglie
parent 13c3750ecf
commit 8128525e83

View File

@ -12,6 +12,7 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.StringTokenizer;
import javax.swing.Box; import javax.swing.Box;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
@ -177,21 +178,43 @@ public abstract class AbstractTextMonitor extends AbstractMonitor {
public void message(final String s) { public void message(final String s) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
// Pre-allocate all objects used for streaming data
Date t = new Date();
String now;
StringBuilder out = new StringBuilder(16384);
public void run() { public void run() {
if (addTimeStampBox.isSelected()) { if (addTimeStampBox.isSelected()) {
String[] lines = s.split("(?<=\\n)"); t.setTime(System.currentTimeMillis());
Document doc = textArea.getDocument(); now = logDateFormat.format(t);
for (String currentLine : lines) { out.setLength(0);
try {
if (doc.getLength() == 0 || ((int) doc.getText(doc.getLength() - 1, 1).charAt(0) == 10)) { boolean isStartingLine;
textArea.append(logDateFormat.format(new Date()) + " -> " + currentLine); try {
} else { Document doc = textArea.getDocument();
textArea.append(currentLine); isStartingLine = doc.getLength() == 0 || ((int) doc.getText(doc.getLength() - 1, 1).charAt(0) == 10);
} } catch (BadLocationException e) {
} catch (BadLocationException e) { // Should not happen but...
e.printStackTrace(); e.printStackTrace();
return;
}
StringTokenizer tokenizer = new StringTokenizer(s, "\n", true);
while (tokenizer.hasMoreTokens()) {
if (isStartingLine) {
out.append(now);
out.append(" -> ");
}
out.append(tokenizer.nextToken());
// Check if we have a "\n" token
if (tokenizer.hasMoreTokens()) {
out.append(tokenizer.nextToken());
isStartingLine = true;
} }
} }
textArea.append(out.toString());
} else { } else {
textArea.append(s); textArea.append(s);
} }