From 8b24cd1fb06c8ad86606cf2296892bbb21f90143 Mon Sep 17 00:00:00 2001 From: "Gary D. Gregory" Date: Mon, 9 May 2016 08:49:57 +0000 Subject: [PATCH] [CSV-181] Make CSVPrinter.print(Object) GC-free. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/csv/trunk@1742895 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 3 ++ .../org/apache/commons/csv/CSVPrinter.java | 28 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 722ed206..ce9a959a 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -38,6 +38,9 @@ Release Notes + + Make CSVPrinter.print(Object) GC-free. + Add shortcut method for using first record as header to CSVFormat Add withHeader(Class<? extends Enum>) to CSVFormat diff --git a/src/main/java/org/apache/commons/csv/CSVPrinter.java b/src/main/java/org/apache/commons/csv/CSVPrinter.java index dc23e1b9..cdd2c11e 100644 --- a/src/main/java/org/apache/commons/csv/CSVPrinter.java +++ b/src/main/java/org/apache/commons/csv/CSVPrinter.java @@ -121,15 +121,33 @@ public final class CSVPrinter implements Flushable, Closeable { */ public void print(final Object value) throws IOException { // null values are considered empty - String strValue; + // Only call CharSequence.toString() if you have to, helps GC-free use cases. + CharSequence charSequence; if (value == null) { final String nullString = format.getNullString(); - strValue = nullString == null ? Constants.EMPTY : nullString; + charSequence = nullString == null ? Constants.EMPTY : nullString; } else { - strValue = value.toString(); + charSequence = value instanceof CharSequence ? (CharSequence) value : value.toString(); } - strValue = format.getTrim() ? strValue.trim() : strValue; - this.print(value, strValue, 0, strValue.length()); + charSequence = format.getTrim() ? trim(charSequence) : charSequence; + this.print(value, charSequence, 0, charSequence.length()); + } + + private CharSequence trim(final CharSequence charSequence) { + if (charSequence instanceof String) { + return ((String) charSequence).trim(); + } + final int count = charSequence.length(); + int len = count; + int pos = 0; + + while ((pos < len) && (charSequence.charAt(pos) <= ' ')) { + pos++; + } + while ((pos < len) && (charSequence.charAt(len - 1) <= ' ')) { + len--; + } + return (pos > 0) || (len < count) ? charSequence.subSequence(pos, len) : charSequence; } private void print(final Object object, final CharSequence value, final int offset, final int len)