From 2ecf983ce00dc338ce2bf85d35abf6b2b35df635 Mon Sep 17 00:00:00 2001 From: Oliver Siegmar Date: Mon, 1 Jan 2024 18:44:28 +0100 Subject: [PATCH] optimize performance --- .../de/siegmar/fastcsv/writer/CsvWriter.java | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java b/lib/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java index aa44bbce..0c0382e0 100644 --- a/lib/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java +++ b/lib/src/main/java/de/siegmar/fastcsv/writer/CsvWriter.java @@ -143,15 +143,15 @@ private void writeInternal(final String value, final int fieldIdx) throws IOExce return; } - final boolean hasDelimiters = hasDelimiters(value, fieldIdx, length); - final boolean needsQuotes = hasDelimiters + final boolean needsEscape = containsControlCharacter(value, fieldIdx, length); + final boolean needsQuotes = needsEscape || quoteStrategy != null && quoteStrategy.quoteNonEmpty(currentLineNo, fieldIdx, value); if (needsQuotes) { writer.write(quoteCharacter); } - if (hasDelimiters) { + if (needsEscape) { writeEscaped(writer, value, quoteCharacter); } else { writer.write(value, 0, length); @@ -162,12 +162,28 @@ private void writeInternal(final String value, final int fieldIdx) throws IOExce } } - @SuppressWarnings("checkstyle:BooleanExpressionComplexity") - private boolean hasDelimiters(final String value, final int fieldIdx, final int length) { + @SuppressWarnings({ + "checkstyle:BooleanExpressionComplexity", + "checkstyle:ReturnCount", + "checkstyle:MagicNumber", + "PMD.AvoidLiteralsInIfCondition" + }) + private boolean containsControlCharacter(final String value, final int fieldIdx, final int length) { + if (fieldIdx == 0 && value.charAt(0) == commentCharacter) { + return true; + } + + // For longer values, indexOf is faster than iterating over the string + if (length > 20) { + return value.indexOf(quoteCharacter) != -1 + || value.indexOf(fieldSeparator) != -1 + || value.indexOf(LF) != -1 + || value.indexOf(CR) != -1; + } + for (int i = 0; i < length; i++) { final char c = value.charAt(i); - if (c == quoteCharacter || c == fieldSeparator || c == LF || c == CR - || c == commentCharacter && fieldIdx == 0 && i == 0) { + if (c == quoteCharacter || c == fieldSeparator || c == LF || c == CR) { return true; } }