java 将CharSequence解析为double而不创建String

5jdjgkvh  于 2023-02-18  发布在  Java
关注(0)|答案(2)|浏览(175)

我需要在Java中解析几千兆字节、几亿行的文本数据。
每行存储在CharBuffer(实现CharSequence)中,并在固定位置包含多个整数和浮点数。
在第一个版本中,我使用了String.substring​(int beginIndex, int endIndex)Integer.parseInt​(String s)以及Double.parseDouble​(String s),但是速度非常慢。垃圾收集器消耗了大量资源,因为每行多次创建几十个临时String对象。
在我切换到Integer.parseInt​(CharSequence s, int beginIndex, int endIndex, int radix)之后,我得到了一个重大的性能提升。它可以直接从CharBuffer解析数字。
不幸的是,我找不到这样的方法浮点数。
有人知道一个方法或库,它提供CharSequence上的浮点解析和偏移量,而不是String吗?

ifsvaxew

ifsvaxew1#

因为我不确定它是否满足了您的所有期望,所以this library似乎可以提供您正在寻找的东西。
它提供了以下方法:

double parseDouble(java.lang.CharSequence s, int start, int end) throws java.lang.NumberFormatException
  • 如果这不是你想要的,抱歉占用你的时间 *
roejwanj

roejwanj2#

这是我以前做的,解析过程中不分配对象,代码可以缩短。

public class NumberParser {

    public static double parseDouble(CharSequence chars) {
        long left = 0;
        long right = 0;
        long numRight = 0;
        int negateFactor = 1;
        boolean isDecimal = false;
        for (int i = 0; i < chars.length(); i++) {
            char ch = chars.charAt(i);

            if (ch == '-') {
                negateFactor = -1;
                continue;
            }

            if (ch == '.') {
                isDecimal = true;
                continue;
            }

            int digit = Character.getNumericValue(ch);
            if (!isDecimal) {
                if (left == 0) {
                    left = digit;
                } else {
                    left *= 10;
                    left += digit;
                }
            } else {
                numRight++;
                if (numRight >= 9) break;
                if (right == 0) {
                    right = digit;
                } else {
                    right *= 10;
                    right += digit;
                }
            }
        }

        double decimal = left + right * Math.pow(10, -numRight);
        decimal *= negateFactor;
        return decimal;
    }
}

相关问题