diff --git a/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromByteArray.java b/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromByteArray.java index b6215f3d..78f06a7e 100644 --- a/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromByteArray.java +++ b/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromByteArray.java @@ -146,8 +146,8 @@ public BigDecimal parseBigDecimalString(byte[] str, int offset, int length) { BigDecimal parseBigDecimalStringWithManyDigits(byte[] str, int offset, int length) { final int integerPartIndex; final int nonZeroIntegerPartIndex; - int decimalPointIndex = -1; int nonZeroFractionalPartIndex = -1; + int decimalPointIndex = -1; final int exponentIndicatorIndex; final int endIndex = offset + length; @@ -169,7 +169,9 @@ BigDecimal parseBigDecimalStringWithManyDigits(byte[] str, int offset, int lengt // ----------------- // skip leading zeroes integerPartIndex = index; - while (index < endIndex - 8 && FastDoubleSwar.isEightZeroes(str, index)) { + // swarLimit: We can process blocks of eight chars with SWAR, we must process the remaining chars individually. + int swarLimit = Math.min(endIndex - 8, 1 << 30); + while (index < swarLimit && FastDoubleSwar.isEightZeroes(str, index)) { index += 8; } while (index < endIndex && str[index] == '0') { @@ -177,7 +179,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(byte[] str, int offset, int lengt } // Count digits of integer part nonZeroIntegerPartIndex = index; - while (index < endIndex - 8 && FastDoubleSwar.isEightDigits(str, index)) { + while (index < swarLimit && FastDoubleSwar.isEightDigits(str, index)) { index += 8; } while (index < endIndex && FastDoubleSwar.isDigit(ch = str[index])) { @@ -186,7 +188,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(byte[] str, int offset, int lengt if (ch == '.') { decimalPointIndex = index++; // skip leading zeroes - while (index < endIndex - 8 && FastDoubleSwar.isEightZeroes(str, index)) { + while (index < swarLimit && FastDoubleSwar.isEightZeroes(str, index)) { index += 8; } while (index < endIndex && str[index] == '0') { @@ -194,7 +196,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(byte[] str, int offset, int lengt } nonZeroFractionalPartIndex = index; // Count digits of fraction part - while (index < endIndex - 8 && FastDoubleSwar.isEightDigits(str, index)) { + while (index < swarLimit && FastDoubleSwar.isEightDigits(str, index)) { index += 8; } while (index < endIndex && FastDoubleSwar.isDigit(ch = str[index])) { @@ -247,8 +249,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(byte[] str, int offset, int lengt illegal |= integerPartIndex == decimalPointIndex && decimalPointIndex == exponentIndicatorIndex; checkParsedBigDecimalBounds(illegal, index, endIndex, digitCountWithoutLeadingZeros, exponent); - return valueOfBigDecimalString(str, nonZeroIntegerPartIndex, decimalPointIndex, nonZeroFractionalPartIndex, exponentIndicatorIndex, isNegative, (int) exponent - ); + return valueOfBigDecimalString(str, nonZeroIntegerPartIndex, decimalPointIndex, nonZeroFractionalPartIndex, exponentIndicatorIndex, isNegative, (int) exponent); } /** @@ -313,7 +314,7 @@ BigDecimal valueOfBigDecimalString(byte[] str, int integerPartIndex, int decimal } else { fractionalPart = ParseDigitsTaskByteArray.parseDigitsIterative(str, nonZeroFractionalPartIndex, exponentIndicatorIndex); } - // If the integer part is not 0, we combine it with the fraction part. + // If the integer part is 0, we can just use the fractional part. if (integerPart.signum() == 0) { significand = fractionalPart; } else { diff --git a/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharArray.java b/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharArray.java index 514dfae2..a8ff1b4c 100644 --- a/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharArray.java +++ b/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharArray.java @@ -141,8 +141,8 @@ public BigDecimal parseBigDecimalString(char[] str, int offset, int length) { * Parses a big decimal string that has many digits. */ BigDecimal parseBigDecimalStringWithManyDigits(char[] str, int offset, int length) { - final int nonZeroIntegerPartIndex; final int integerPartIndex; + final int nonZeroIntegerPartIndex; int nonZeroFractionalPartIndex = -1; int decimalPointIndex = -1; final int exponentIndicatorIndex; @@ -164,7 +164,9 @@ BigDecimal parseBigDecimalStringWithManyDigits(char[] str, int offset, int lengt // Count digits of significand // ----------------- + // skip leading zeroes integerPartIndex = index; + // swarLimit: We can process blocks of eight chars with SWAR, we must process the remaining chars individually. int swarLimit = Math.min(endIndex - 8, 1 << 30); while (index < swarLimit && FastDoubleSwar.isEightZeroes(str, index)) { index += 8; @@ -244,10 +246,10 @@ BigDecimal parseBigDecimalStringWithManyDigits(char[] str, int offset, int lengt illegal |= integerPartIndex == decimalPointIndex && decimalPointIndex == exponentIndicatorIndex; checkParsedBigDecimalBounds(illegal, index, endIndex, digitCountWithoutLeadingZeros, exponent); - return valueOfBigDecimalString(str, nonZeroIntegerPartIndex, decimalPointIndex, nonZeroFractionalPartIndex, exponentIndicatorIndex, isNegative, (int) exponent); + return valueOfBigDecimalString(str, nonZeroIntegerPartIndex, decimalPointIndex, nonZeroFractionalPartIndex, exponentIndicatorIndex, isNegative, (int) exponent + ); } - /** * Parses a big decimal string after we have identified the parts of the significand, * and after we have obtained the exponent value. @@ -273,8 +275,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(char[] str, int offset, int lengt * @return the parsed big decimal */ BigDecimal valueOfBigDecimalString(char[] str, int integerPartIndex, int decimalPointIndex, int nonZeroFractionalPartIndex, int exponentIndicatorIndex, boolean isNegative, int exponent) { - int integerExponent = exponentIndicatorIndex - decimalPointIndex - 1; - int fractionDigitsCount = exponentIndicatorIndex - nonZeroFractionalPartIndex; + int fractionDigitsCount = exponentIndicatorIndex - decimalPointIndex - 1; int nonZeroFractionDigitsCount = exponentIndicatorIndex - nonZeroFractionalPartIndex; int integerDigitsCount = decimalPointIndex - integerPartIndex; NavigableMap powersOfTen = null; @@ -306,16 +307,16 @@ BigDecimal valueOfBigDecimalString(char[] str, int integerPartIndex, int decimal if (powersOfTen == null) { powersOfTen = createPowersOfTenFloor16Map(); } - fillPowersOfNFloor16Recursive(powersOfTen, decimalPointIndex + 1, exponentIndicatorIndex); - fractionalPart = ParseDigitsTaskCharArray.parseDigitsRecursive(str, decimalPointIndex + 1, exponentIndicatorIndex, powersOfTen, RECURSION_THRESHOLD); + fillPowersOfNFloor16Recursive(powersOfTen, nonZeroFractionalPartIndex, exponentIndicatorIndex); + fractionalPart = ParseDigitsTaskCharArray.parseDigitsRecursive(str, nonZeroFractionalPartIndex, exponentIndicatorIndex, powersOfTen, RECURSION_THRESHOLD); } else { - fractionalPart = ParseDigitsTaskCharArray.parseDigitsIterative(str, decimalPointIndex + 1, exponentIndicatorIndex); + fractionalPart = ParseDigitsTaskCharArray.parseDigitsIterative(str, nonZeroFractionalPartIndex, exponentIndicatorIndex); } - // If the integer part is not 0, we combine it with the fraction part. + // If the integer part is 0, we can just use the fractional part. if (integerPart.signum() == 0) { significand = fractionalPart; } else { - BigInteger integerFactor = computePowerOfTen(powersOfTen, integerExponent); + BigInteger integerFactor = computePowerOfTen(powersOfTen, fractionDigitsCount); significand = FftMultiplier.multiply(integerPart, integerFactor).add(fractionalPart); } } else { diff --git a/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharSequence.java b/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharSequence.java index 8fb1dc13..88363694 100644 --- a/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharSequence.java +++ b/fastdoubleparser-dev/src/main/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JavaBigDecimalFromCharSequence.java @@ -38,8 +38,7 @@ public JavaBigDecimalFromCharSequence() { */ public BigDecimal parseBigDecimalString(CharSequence str, int offset, int length) { try { - int size = str.length(); - final int endIndex = checkBounds(size, offset, length); + final int endIndex = checkBounds(str.length(), offset, length); if (hasManyDigits(length)) { return parseBigDecimalStringWithManyDigits(str, offset, length); } @@ -137,7 +136,6 @@ public BigDecimal parseBigDecimalString(CharSequence str, int offset, int length nfe.initCause(e); throw nfe; } - } /** @@ -146,8 +144,8 @@ public BigDecimal parseBigDecimalString(CharSequence str, int offset, int length BigDecimal parseBigDecimalStringWithManyDigits(CharSequence str, int offset, int length) { final int integerPartIndex; final int nonZeroIntegerPartIndex; - int decimalPointIndex = -1; int nonZeroFractionalPartIndex = -1; + int decimalPointIndex = -1; final int exponentIndicatorIndex; final int endIndex = offset + length; @@ -169,7 +167,9 @@ BigDecimal parseBigDecimalStringWithManyDigits(CharSequence str, int offset, int // ----------------- // skip leading zeroes integerPartIndex = index; - while (index < endIndex - 8 && FastDoubleSwar.isEightZeroes(str, index)) { + // swarLimit: We can process blocks of eight chars with SWAR, we must process the remaining chars individually. + int swarLimit = Math.min(endIndex - 8, 1 << 30); + while (index < swarLimit && FastDoubleSwar.isEightZeroes(str, index)) { index += 8; } while (index < endIndex && str.charAt(index) == '0') { @@ -177,7 +177,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(CharSequence str, int offset, int } // Count digits of integer part nonZeroIntegerPartIndex = index; - while (index < endIndex - 8 && FastDoubleSwar.isEightDigits(str, index)) { + while (index < swarLimit && FastDoubleSwar.isEightDigits(str, index)) { index += 8; } while (index < endIndex && FastDoubleSwar.isDigit(ch = str.charAt(index))) { @@ -186,7 +186,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(CharSequence str, int offset, int if (ch == '.') { decimalPointIndex = index++; // skip leading zeroes - while (index < endIndex - 8 && FastDoubleSwar.isEightZeroes(str, index)) { + while (index < swarLimit && FastDoubleSwar.isEightZeroes(str, index)) { index += 8; } while (index < endIndex && str.charAt(index) == '0') { @@ -194,7 +194,7 @@ BigDecimal parseBigDecimalStringWithManyDigits(CharSequence str, int offset, int } nonZeroFractionalPartIndex = index; // Count digits of fraction part - while (index < endIndex - 8 && FastDoubleSwar.isEightDigits(str, index)) { + while (index < swarLimit && FastDoubleSwar.isEightDigits(str, index)) { index += 8; } while (index < endIndex && FastDoubleSwar.isDigit(ch = str.charAt(index))) { @@ -312,6 +312,7 @@ BigDecimal valueOfBigDecimalString(CharSequence str, int integerPartIndex, int d } else { fractionalPart = ParseDigitsTaskCharSequence.parseDigitsIterative(str, nonZeroFractionalPartIndex, exponentIndicatorIndex); } + // If the integer part is 0, we can just use the fractional part. if (integerPart.signum() == 0) { significand = fractionalPart; } else { diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/AbstractBigDecimalParserTest.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/AbstractBigDecimalParserTest.java index 8ebc2a87..526fca85 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/AbstractBigDecimalParserTest.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/AbstractBigDecimalParserTest.java @@ -135,12 +135,15 @@ protected List createDataForLegalDecStrings() { new NumberTestDataSupplier("min exponent", () -> new NumberTestData("1e" + (Integer.MIN_VALUE + 1), BigDecimal.ONE.scaleByPowerOfTen(Integer.MIN_VALUE + 1))), new NumberTestDataSupplier("max exponent", () -> new NumberTestData("1e" + Integer.MAX_VALUE, BigDecimal.ONE.scaleByPowerOfTen(Integer.MAX_VALUE))), - new NumberTestDataSupplier("8.99...99e68", () -> new NumberTestData("8." + (repeat("9", 19)) + "e68", new BigDecimal("8." + (repeat("9", 19)) + "e68"))), + new NumberTestDataSupplier("8.99...99e68", () -> new NumberTestData("8." + (repeat('9', 19)) + "e68", new BigDecimal("8." + (repeat('9', 19)) + "e68"))), new NumberTestDataSupplier("103203303403503603703803903.122232425262728292", () -> new NumberTestData("103203303403503603703803903.122232425262728292", new BigDecimal("103203303403503603703803903.122232425262728292"))), new NumberTestDataSupplier("122232425262728292.103203303403503603703803903", () -> new NumberTestData("122232425262728292.103203303403503603703803903", new BigDecimal("122232425262728292.103203303403503603703803903"))), new NumberTestDataSupplier("-103203303403503603703803903.122232425262728292e6789", () -> new NumberTestData("-103203303403503603703803903.122232425262728292e6789", new BigDecimal("-103203303403503603703803903.122232425262728292e6789"))), new NumberTestDataSupplier("122232425262728292.103203303403503603703803903e-6789", () -> new NumberTestData("122232425262728292.103203303403503603703803903e-6789", new BigDecimal("122232425262728292.103203303403503603703803903e-6789"))), - new NumberTestDataSupplier("-122232425262728292.103203303403503603703803903e-6789", () -> new NumberTestData("-122232425262728292.103203303403503603703803903e-6789", new BigDecimal("-122232425262728292.103203303403503603703803903e-6789"))) + new NumberTestDataSupplier("-122232425262728292.103203303403503603703803903e-6789", () -> new NumberTestData("-122232425262728292.103203303403503603703803903e-6789", new BigDecimal("-122232425262728292.103203303403503603703803903e-6789"))), + new NumberTestDataSupplier("-11000.0..0(652 fractional digits)", + () -> new NumberTestData("-11000." + repeat('0', 652), + new BigDecimal("-11000." + repeat('0', 652)))) ); } @@ -239,16 +242,16 @@ protected List createTestDataForInputClassesInMethodPars */ protected List createTestDataForInputClassesInMethodParseBigDecimalStringWithManyDigits() { return Arrays.asList( - new NumberTestDataSupplier("illegal only negative sign", () -> new NumberTestData("-" + repeat("\000", 32), AbstractNumberParser.SYNTAX_ERROR, NumberFormatException.class)), - new NumberTestDataSupplier("illegal only positive sign", () -> new NumberTestData("+" + repeat("\000", 32), AbstractNumberParser.SYNTAX_ERROR, NumberFormatException.class)), + new NumberTestDataSupplier("illegal only negative sign", () -> new NumberTestData("-" + repeat('\000', 32), AbstractNumberParser.SYNTAX_ERROR, NumberFormatException.class)), + new NumberTestDataSupplier("illegal only positive sign", () -> new NumberTestData("+" + repeat('\000', 32), AbstractNumberParser.SYNTAX_ERROR, NumberFormatException.class)), new NumberTestDataSupplier("significand with 40 zeroes in integer part", () -> new NumberTestData("significand with 40 zeroes in integer part", repeat("0", 40), BigDecimal::new)), - new NumberTestDataSupplier("significand with 40 zeroes in fraction part", () -> new NumberTestData("." + repeat("0", 40), BigDecimal::new)), + new NumberTestDataSupplier("significand with 40 zeroes in fraction part", () -> new NumberTestData("." + repeat('0', 40), BigDecimal::new)), - new NumberTestDataSupplier("significand with 10 leading zeros and 30 digits in integer part", () -> new NumberTestData("significand with 10 leading zeros and 30 digits in integer part", repeat("0", 10) + repeat("9", 30), BigDecimal::new)), - new NumberTestDataSupplier("significand with 10 leading zeros and 30 digits in fraction part", () -> new NumberTestData("." + repeat("0", 10) + repeat("9", 30), BigDecimal::new)), - new NumberTestDataSupplier("significand with 10 leading zeros and 30 digits in integer part and in fraction part", () -> new NumberTestData("significand with 10 leading zeros and 30 digits in integer part and in fraction part", repeat("0", 10) + repeat("9", 30) + "." + repeat("0", 10) + repeat("9", 30), BigDecimal::new)), + new NumberTestDataSupplier("significand with 10 leading zeros and 30 digits in integer part", () -> new NumberTestData("significand with 10 leading zeros and 30 digits in integer part", repeat('0', 10) + repeat('9', 30), BigDecimal::new)), + new NumberTestDataSupplier("significand with 10 leading zeros and 30 digits in fraction part", () -> new NumberTestData("." + repeat('0', 10) + repeat('9', 30), BigDecimal::new)), + new NumberTestDataSupplier("significand with 10 leading zeros and 30 digits in integer part and in fraction part", () -> new NumberTestData("significand with 10 leading zeros and 30 digits in integer part and in fraction part", repeat('0', 10) + repeat("9", 30) + "." + repeat("0", 10) + repeat("9", 30), BigDecimal::new)), new NumberTestDataSupplier("significand with 40 digits in integer part and exponent", () -> new NumberTestData("-1234567890123456789012345678901234567890e887799", BigDecimal::new)), new NumberTestDataSupplier("no significand but exponent 40 digits", () -> new NumberTestData("-e12345678901234567890123456789012345678901234567890", AbstractNumberParser.SYNTAX_ERROR, NumberFormatException.class)), diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/FftMultiplierTest.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/FftMultiplierTest.java index 1ef2e532..b4816612 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/FftMultiplierTest.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/FftMultiplierTest.java @@ -31,17 +31,17 @@ public List dynamicTestsMultiply() { "2147483647", "9223372036854775807")), dynamicTest("'3','0'**84 * '4','0'**84", () -> shouldMultiplyFft( - "3" + repeat("0", 84), - "4" + repeat("0", 84))), + "3" + repeat('0', 84), + "4" + repeat('0', 84))), dynamicTest("'-','3','0'**84 * '4','0'**84", () -> shouldMultiplyFft( - "-3" + repeat("0", 84), - "4" + repeat("0", 84))), + "-3" + repeat('0', 84), + "4" + repeat('0', 84))), dynamicTest("'-','3','0'**84 * '-','4','0'**84", () -> shouldMultiplyFft( - "-3" + repeat("0", 84), - "-4" + repeat("0", 84))), + "-3" + repeat('0', 84), + "-4" + repeat('0', 84))), dynamicTest("'3','0'**100_000 * '4','0'**100_000", () -> shouldMultiplyFft( - "3" + repeat("0", 100_000), - "4" + repeat("0", 100_000))) + "3" + repeat('0', 100_000), + "4" + repeat('0', 100_000))) ); } @@ -140,16 +140,16 @@ private void shouldMultiplyFft(BigInteger a, BigInteger b, BigInteger expected) public List dynamicTestsSquare() { return Arrays.asList( dynamicTest("'3','0'**84", () -> shouldSquare( - "3" + repeat("0", 84) + "3" + repeat('0', 84) )), dynamicTest("'-','3','0'**84", () -> shouldSquare( - "-3" + repeat("0", 84) + "-3" + repeat('0', 84) )), dynamicTest("'-','3','0'**84", () -> shouldSquare( - "-3" + repeat("0", 84) + "-3" + repeat('0', 84) )), dynamicTest("'3','0'**100_000", () -> shouldSquare( - "3" + repeat("0", 100_000) + "3" + repeat('0', 100_000) )) ); diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhBigDecimalScalability.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhBigDecimalScalability.java index 06a42f70..5ddd2a50 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhBigDecimalScalability.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhBigDecimalScalability.java @@ -4,7 +4,18 @@ */ package ch.randelshofer.fastdoubleparser; -import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.math.BigDecimal; import java.util.concurrent.TimeUnit; @@ -63,7 +74,7 @@ public class JmhBigDecimalScalability { @Setup(Level.Trial) public void setUp() { - str = repeat("7", digits); + str = repeat('7', digits); } @Benchmark diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhDoubleScalability.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhDoubleScalability.java index e6e0141f..29a10ceb 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhDoubleScalability.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhDoubleScalability.java @@ -4,7 +4,18 @@ */ package ch.randelshofer.fastdoubleparser; -import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -67,7 +78,7 @@ public class JmhDoubleScalability { @Setup(Level.Trial) public void setUp() { - str = repeat("7", digits); + str = repeat('7', digits); } @Benchmark diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaBigIntegerFromByteArrayScalability.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaBigIntegerFromByteArrayScalability.java index d8dc3e7e..071b1b68 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaBigIntegerFromByteArrayScalability.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaBigIntegerFromByteArrayScalability.java @@ -97,12 +97,12 @@ public class JmhJavaBigIntegerFromByteArrayScalability { @Setup(Level.Trial) public void setUp() { String str = "-" - + repeat("0", Math.max(0, digits - 646456993)) + + repeat('0', Math.max(0, digits - 646456993)) + repeat("1234567890", (Math.min(646456993, digits) + 9) / 10).substring(0, Math.min(digits, 646456993)); decLiteral = str.getBytes(StandardCharsets.ISO_8859_1); str = "-" - + repeat("0", Math.max(0, digits - 536870912)) + + repeat('0', Math.max(0, digits - 536870912)) + repeat("12b4c6d7e0", (Math.min(536870912, digits) + 9) / 10).substring(0, Math.min(digits, 536870912)); hexLiteral = str.getBytes(StandardCharsets.ISO_8859_1); diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaDoubleFromCharSequenceScalability.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaDoubleFromCharSequenceScalability.java index e73818bd..b31b6ca9 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaDoubleFromCharSequenceScalability.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/JmhJavaDoubleFromCharSequenceScalability.java @@ -4,7 +4,18 @@ */ package ch.randelshofer.fastdoubleparser; -import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; import java.util.concurrent.TimeUnit; @@ -70,7 +81,7 @@ public class JmhJavaDoubleFromCharSequenceScalability { @Setup(Level.Trial) public void setUp() { - str = repeat("7", digits - 2); + str = repeat('7', digits - 2); } @Benchmark diff --git a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/Strings.java b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/Strings.java index 12542c9f..36726d4b 100644 --- a/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/Strings.java +++ b/fastdoubleparser-dev/src/test/java/ch.randelshofer.fastdoubleparser/ch/randelshofer/fastdoubleparser/Strings.java @@ -4,6 +4,9 @@ */ package ch.randelshofer.fastdoubleparser; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + public class Strings { public static StringBuilder repeatStringBuilder(String str, int count) { StringBuilder b = new StringBuilder(str.length() * count); @@ -16,4 +19,15 @@ public static StringBuilder repeatStringBuilder(String str, int count) { public static String repeat(String str, int count) { return repeatStringBuilder(str, count).toString(); } + + public static String repeat(char ch, int count) { + if (ch < 256) { + byte[] chars = new byte[count]; + Arrays.fill(chars, (byte) ch); + return new String(chars, StandardCharsets.ISO_8859_1); + } + char[] chars = new char[count]; + Arrays.fill(chars, ch); + return String.copyValueOf(chars); + } }