aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Stadler <centic@apache.org>2024-07-15 05:41:14 +0000
committerDominik Stadler <centic@apache.org>2024-07-15 05:41:14 +0000
commit719e7154a19c00e1c2464e5f93a1567d8ca5ed72 (patch)
tree7770905ba7f96075670ac8f354bfe11b671584fa
parenta9717512382201ee290a4d1e52c6f195db16e8ab (diff)
downloadpoi-719e7154a19c00e1c2464e5f93a1567d8ca5ed72.tar.gz
poi-719e7154a19c00e1c2464e5f93a1567d8ca5ed72.zip
Optimize generating numbers for bullets in Word
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
-rw-r--r--poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/NumberFormatter.java11
1 files changed, 8 insertions, 3 deletions
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/NumberFormatter.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/NumberFormatter.java
index 087add5cbf..483c227c23 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/NumberFormatter.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/NumberFormatter.java
@@ -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;