]> source.dussan.org Git - poi.git/commitdiff
Optimize generating numbers for bullets in Word
authorDominik Stadler <centic@apache.org>
Mon, 15 Jul 2024 05:41:14 +0000 (05:41 +0000)
committerDominik Stadler <centic@apache.org>
Mon, 15 Jul 2024 05:41:14 +0000 (05:41 +0000)
Using char[] instead of String improves performance of this
operation considerably, especially in JDK 11+ where StringBuilder
was switched to work on bytes instead of chars.

This is likely only relevant for very large documents, it was visible
in a synthetic test-file from fuzzing.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1919239 13f79535-47bb-0310-9956-ffa450edef68

poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/NumberFormatter.java

index 087add5cbfc69c3a03d60f9f9ed154a87775b1d0..483c227c23be6f9eb0317c0640287a9cdaaa24ac 100644 (file)
@@ -19,6 +19,7 @@
 
 package org.apache.poi.hwpf.converter;
 
+import java.util.Arrays;
 import java.util.Locale;
 
 import org.apache.poi.util.Beta;
@@ -28,8 +29,12 @@ import org.apache.poi.util.Beta;
  */
 @Beta
 public final class NumberFormatter {
-    private static final String[] ROMAN_LETTERS = { "m", "cm", "d", "cd", "c",
-            "xc", "l", "xl", "x", "ix", "v", "iv", "i" };
+    // use char[] instead of String to speed up StringBuilder.append(), especially in JDK 11+
+    // where StringBuilder internally switched from char[] to byte[]
+    private static final char[][] ROMAN_LETTERS = Arrays.stream(
+            new String[] { "m", "cm", "d", "cd", "c", "xc", "l", "xl", "x", "ix", "v", "iv", "i" }).
+                map(String::toCharArray).
+                toArray(char[][]::new);
 
     private static final int[] ROMAN_VALUES = { 1000, 900, 500, 400, 100, 90,
             50, 40, 10, 9, 5, 4, 1 };
@@ -86,7 +91,7 @@ public final class NumberFormatter {
         StringBuilder result = new StringBuilder();
 
         for ( int i = 0; i < ROMAN_LETTERS.length; i++ ) {
-            String letter = ROMAN_LETTERS[i];
+            char[] letter = ROMAN_LETTERS[i];
             int value = ROMAN_VALUES[i];
             while ( number >= value ) {
                 number -= value;