Class FastDoubleSwar


  • final class FastDoubleSwar
    extends java.lang.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 Summary

      Fields 
      Modifier and Type Field Description
      private static java.lang.invoke.VarHandle readIntBE  
      private static java.lang.invoke.VarHandle readIntLE  
      private static java.lang.invoke.VarHandle readLongBE  
      private static java.lang.invoke.VarHandle readLongLE  
    • Constructor Summary

      Constructors 
      Constructor Description
      FastDoubleSwar()  
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static double fma​(double a, double b, double c)  
      protected static boolean isDigit​(byte c)
      Checks if '0' <= c && c <= '9'.
      protected static boolean isDigit​(char c)
      Checks if '0' <= c && c <= '9'.
      static boolean isEightDigits​(byte[] a, int offset)  
      static boolean isEightDigits​(char[] a, int offset)
      Checks if the string contains eight digits at the specified offset.
      static boolean isEightDigits​(java.lang.CharSequence a, int offset)  
      static boolean isEightDigitsUtf16​(long first, long second)  
      static boolean isEightDigitsUtf8​(long chunk)  
      static boolean isEightZeroes​(byte[] a, int offset)  
      static boolean isEightZeroes​(char[] a, int offset)
      Checks if the string contains eight zeroes at the specified offset.
      static boolean isEightZeroes​(java.lang.CharSequence a, int offset)  
      static boolean isEightZeroesUtf16​(long first, long second)  
      static boolean isEightZeroesUtf8​(long chunk)  
      static int readIntBE​(byte[] a, int offset)  
      static long readLongBE​(byte[] a, int offset)  
      static long readLongLE​(byte[] a, int offset)  
      static int tryToParseEightDigits​(byte[] a, int offset)  
      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).
      static int tryToParseEightDigits​(java.lang.CharSequence str, int offset)
      Tries to parse eight digits at once using the 'SIMD within a register technique' (SWAR).
      static int tryToParseEightDigitsUtf16​(long first, long second)
      Tries to parse eight decimal digits at once using the 'SIMD within a register technique' (SWAR).
      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).
      static int tryToParseEightDigitsUtf8​(long chunk)
      Tries to parse eight digits from a long using the 'SIMD within a register technique' (SWAR).
      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).
      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).
      static long tryToParseEightHexDigits​(java.lang.CharSequence str, int offset)
      Tries to parse eight digits at once using the 'SIMD within a register technique' (SWAR).
      static long tryToParseEightHexDigitsUtf16​(long first, long second)
      Tries to parse eight hex digits from two longs using the 'SIMD within a register technique' (SWAR).
      static long tryToParseEightHexDigitsUtf8​(long chunk)
      Tries to parse eight digits from a long using the 'SIMD within a register technique' (SWAR).
      static int tryToParseFourDigits​(byte[] a, int offset)  
      static int tryToParseFourDigits​(char[] a, int offset)  
      static int tryToParseFourDigits​(java.lang.CharSequence str, int offset)  
      static int tryToParseFourDigitsUtf16​(long first)  
      static int tryToParseFourDigitsUtf8​(int chunk)  
      static int tryToParseUpTo7Digits​(byte[] str, int from, int to)  
      static int tryToParseUpTo7Digits​(char[] str, int from, int to)  
      static int tryToParseUpTo7Digits​(java.lang.CharSequence str, int from, int to)  
      static void writeIntBE​(byte[] a, int offset, int value)  
      static void writeLongBE​(byte[] a, int offset, long value)  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • readLongLE

        private static final java.lang.invoke.VarHandle readLongLE
      • readIntLE

        private static final java.lang.invoke.VarHandle readIntLE
      • readIntBE

        private static final java.lang.invoke.VarHandle readIntBE
      • readLongBE

        private static final java.lang.invoke.VarHandle readLongBE
    • Constructor Detail

      • FastDoubleSwar

        FastDoubleSwar()
    • Method Detail

      • isDigit

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

        protected static boolean isDigit​(byte c)
        Checks if '0' <= c && c <= '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:
        java.lang.IndexOutOfBoundsException - if offset is larger than 2^29.
      • isEightDigits

        public static boolean isEightDigits​(java.lang.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​(java.lang.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:
        java.lang.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:
        java.lang.IndexOutOfBoundsException - if offset is larger than 2^
      • tryToParseEightDigits

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

        public static int tryToParseEightDigits​(java.lang.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​(java.lang.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​(java.lang.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​(java.lang.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)