Class FastDoubleSwar

java.lang.Object
ch.randelshofer.fastdoubleparser.FastDoubleSwar

final class FastDoubleSwar extends Object
This class provides methods for parsing multiple characters at once using the "SIMD with a register" (SWAR) technique.

References:

Leslie Lamport, Multiple Byte Processing with Full-Word Instructions
azurewebsites.net
Daniel Lemire, fast_float number parsing library: 4x faster than strtod. MIT License.
github.com
Daniel Lemire, Number Parsing at a Gigabyte per Second, Software: Practice and Experience 51 (8), 2021. arXiv.2101.11408v3 [cs.DS] 24 Feb 2021
arxiv.org

  • Field Details

    • readLongLE

      private static final VarHandle readLongLE
    • readIntLE

      private static final VarHandle readIntLE
    • readIntBE

      private static final VarHandle readIntBE
    • readLongBE

      private static final VarHandle readLongBE
    • CHAR_ALIGNED_LONG

      private static final ValueLayout.OfLong CHAR_ALIGNED_LONG
  • Constructor Details

    • FastDoubleSwar

      FastDoubleSwar()
  • Method Details

    • countUpToEightDigitsUtf8

      public static int countUpToEightDigitsUtf8(long chunk)
    • isDigit

      protected static boolean isDigit(char c)
      Checks if '0' invalid input: '<'= c invalid input: '&'invalid input: '&' c invalid input: '<'= '9'.
      Parameters:
      c - a character
      Returns:
      true if c is a digit
    • isDigit

      protected static boolean isDigit(byte c)
      Checks if '0' invalid input: '<'= c invalid input: '&'invalid input: '&' c invalid input: '<'= '9'.
      Parameters:
      c - a character
      Returns:
      true if c is a digit
    • isEightDigits

      public static boolean isEightDigits(byte[] a, int offset)
    • isEightDigits

      public static boolean isEightDigits(char[] a, int offset)
      Checks if the string contains eight digits at the specified offset.
      Parameters:
      a - a string
      offset - offset into string
      Returns:
      true if eight digits
      Throws:
      IndexOutOfBoundsException - if offset is larger than 2^29.
    • isEightDigits

      public static boolean isEightDigits(CharSequence a, int offset)
    • isEightDigitsUtf16

      public static boolean isEightDigitsUtf16(long first, long second)
    • isEightDigitsUtf8

      public static boolean isEightDigitsUtf8(long chunk)
    • isEightZeroes

      public static boolean isEightZeroes(byte[] a, int offset)
    • isEightZeroes

      public static boolean isEightZeroes(CharSequence a, int offset)
    • isEightZeroes

      public static boolean isEightZeroes(char[] a, int offset)
      Checks if the string contains eight zeroes at the specified offset.
      Parameters:
      a - a string
      offset - offset into string
      Returns:
      true if eight digits
      Throws:
      IndexOutOfBoundsException - if offset is larger than 2^29.
    • isEightZeroesUtf16

      public static boolean isEightZeroesUtf16(long first, long second)
    • isEightZeroesUtf8

      public static boolean isEightZeroesUtf8(long chunk)
    • readIntBE

      public static int readIntBE(byte[] a, int offset)
    • readLongBE

      public static long readLongBE(byte[] a, int offset)
    • readLongLE

      public static long readLongLE(byte[] a, int offset)
    • tryToParseEightDigits

      public static int tryToParseEightDigits(char[] a, int offset)
      Tries to parse eight decimal digits from a char array using the 'SIMD within a register technique' (SWAR).
      Parameters:
      a - contains 8 utf-16 characters starting at offset
      offset - the offset into the array
      Returns:
      the parsed number, returns a negative value if value does not contain 8 hex digits
      Throws:
      IndexOutOfBoundsException - if offset is larger than 2^29
    • tryToParseEightDigits

      public static int tryToParseEightDigits(byte[] a, int offset)
    • tryToParseEightDigits

      public static int tryToParseEightDigits(CharSequence str, int offset)
      Tries to parse eight digits at once using the 'SIMD within a register technique' (SWAR).
      Parameters:
      str - a character sequence
      offset - the index of the first character in the character sequence
      Returns:
      the parsed digits or -1
    • tryToParseEightDigitsUtf16

      public static int tryToParseEightDigitsUtf16(long first, long second)
      Tries to parse eight decimal digits at once using the 'SIMD within a register technique' (SWAR).
      char[] chars = ...;
      long first  = chars[0]|(chars[1]<<16)|(chars[2]<<32)|(chars[3]<<48);
      long second = chars[4]|(chars[5]<<16)|(chars[6]<<32)|(chars[7]<<48);
      
      Parameters:
      first - the first four characters in big endian order
      second - the second four characters in big endian order
      Returns:
      the parsed digits or -1
    • tryToParseEightDigitsUtf8

      public static int tryToParseEightDigitsUtf8(byte[] a, int offset)
      Tries to parse eight decimal digits from a byte array using the 'SIMD within a register technique' (SWAR).
      Parameters:
      a - contains 8 ascii characters
      offset - the offset of the first character in a
      Returns:
      the parsed number, returns a negative value if value does not contain 8 digits
    • tryToParseEightDigitsUtf8

      public static int tryToParseEightDigitsUtf8(long chunk)
      Tries to parse eight digits from a long using the 'SIMD within a register technique' (SWAR).
      byte[] bytes = ...;
      long value  = ((bytes[7]&0xffL)<<56)
                  | ((bytes[6]&0xffL)<<48)
                  | ((bytes[5]&0xffL)<<40)
                  | ((bytes[4]&0xffL)<<32)
                  | ((bytes[3]&0xffL)<<24)
                  | ((bytes[2]&0xffL)<<16)
                  | ((bytes[1]&0xffL)<< 8)
                  |  (bytes[0]&0xffL);
      
      Parameters:
      chunk - contains 8 ascii characters in little endian order
      Returns:
      the parsed number, or a value < 0 if not all characters are digits.
    • tryToParseEightHexDigits

      public static long tryToParseEightHexDigits(CharSequence str, int offset)
      Tries to parse eight digits at once using the 'SIMD within a register technique' (SWAR).
      Parameters:
      str - a character sequence
      offset - the index of the first character in the character sequence
      Returns:
      the parsed digits or -1
    • tryToParseEightHexDigits

      public static long tryToParseEightHexDigits(char[] chars, int offset)
      Tries to parse eight hex digits from a char array using the 'SIMD within a register technique' (SWAR).
      Parameters:
      chars - contains 8 utf-16 characters starting at offset
      offset - the offset into the array
      Returns:
      the parsed number, returns a negative value if value does not contain 8 hex digits
    • tryToParseEightHexDigits

      public static long tryToParseEightHexDigits(byte[] a, int offset)
      Tries to parse eight hex digits from a byte array using the 'SIMD within a register technique' (SWAR).
      Parameters:
      a - contains 8 ascii characters
      offset - the offset of the first character in a returns a negative value if value does not contain 8 digits
    • tryToParseEightHexDigitsUtf16

      public static long tryToParseEightHexDigitsUtf16(long first, long second)
      Tries to parse eight hex digits from two longs using the 'SIMD within a register technique' (SWAR).
      char[] chars = ...;
      long first  = (long) chars[0] << 48
                  | (long) chars[1] << 32
                  | (long) chars[2] << 16
                  | (long) chars[3];
      
      long second = (long) chars[4] << 48
                  | (long) chars[5] << 32
                  | (long) chars[6] << 16
                  | (long) chars[7];
      
      Parameters:
      first - contains 4 utf-16 characters in big endian order
      second - contains 4 utf-16 characters in big endian order
      Returns:
      the parsed number, returns a negative value if the two longs do not contain 8 hex digits
    • tryToParseEightHexDigitsUtf8

      public static long tryToParseEightHexDigitsUtf8(long chunk)
      Tries to parse eight digits from a long using the 'SIMD within a register technique' (SWAR).
      Parameters:
      chunk - contains 8 ascii characters in big endian order
      Returns:
      the parsed number, returns a negative value if value does not contain 8 digits
    • tryToParseFourDigits

      public static int tryToParseFourDigits(char[] a, int offset)
    • tryToParseFourDigits

      public static int tryToParseFourDigits(CharSequence str, int offset)
    • tryToParseFourDigits

      public static int tryToParseFourDigits(byte[] a, int offset)
    • tryToParseFourDigitsUtf16

      public static int tryToParseFourDigitsUtf16(long first)
    • tryToParseFourDigitsUtf8

      public static int tryToParseFourDigitsUtf8(int chunk)
    • tryToParseUpTo7Digits

      public static int tryToParseUpTo7Digits(byte[] str, int from, int to)
    • tryToParseUpTo7Digits

      public static int tryToParseUpTo7Digits(char[] str, int from, int to)
    • tryToParseUpTo7Digits

      public static int tryToParseUpTo7Digits(CharSequence str, int from, int to)
    • writeIntBE

      public static void writeIntBE(byte[] a, int offset, int value)
    • writeLongBE

      public static void writeLongBE(byte[] a, int offset, long value)
    • fma

      public static double fma(double a, double b, double c)