gpt4 book ai didi

java - Java 中的高效 strtod?

转载 作者:搜寻专家 更新时间:2023-10-31 08:20:55 26 4
gpt4 key购买 nike

所以我有这个 Java 程序,我用它来处理数 TB 的数据。性能是一个问题。

我分析了该应用程序,所有内存分配的很大一部分以及 CPU 时间的很大一部分来自执行一个简单的操作:

我有一个 ASCII 字符数组。我知道从偏移量i到偏移量j的字符代表一个 float 。我需要将该 float 提取到 double 中。

天真的 Double.parseDouble(new String(buf, i, j - i)) 完成了这项工作。然而,这是花费大量时间和大量内存分配的地方,可能是因为:

  • new String() 创建一个新对象,创建一个内部char[] 数组并将字符复制到数组中;
  • Double.parseDouble()创建一个 FloatingDecimal对象,也创建了一个 char[] 数组,还将字符复制到其中。

所有这些分配和所有这些复制都不是真正必要的。我可以避开它们吗?

我真正想要的是 strtod -like 函数,它将采用 char[](或 byte[])以及开始/结束偏移量,并返回 double .

有什么建议吗?我应该自己推出吗?我应该围绕 strtod 编写一个 JNI 包装器吗?我应该使用一些已经存在的 Java 库吗?

最佳答案

我过去所做的是为 ByteBuffer 编写一个解析器(以避免字节到字符编码转换)到 double,反之亦然。如果你能避免创建任何对象,它会更快。这种方法适用于内存映射文件,也避免了一些复制成本。

核心代码如下所示。它不处理指数,但您可以添加它。

@Override
public double read() throws BufferUnderflowException {
long value = 0;
int exp = 0;
boolean negative = false;
int decimalPlaces = Integer.MIN_VALUE;
while (true) {
byte ch = buffer.get();
if (ch >= '0' && ch <= '9') {
while (value >= MAX_VALUE_DIVIDE_10) {
value >>>= 1;
exp++;
}
value = value * 10 + (ch - '0');
decimalPlaces++;
} else if (ch == '-') {
negative = true;
} else if (ch == '.') {
decimalPlaces = 0;
} else {
break;
}
}

return asDouble(value, exp, negative, decimalPlaces);
}

The full code

它一收到任何它不期望的字节就停止,例如,\n

关于java - Java 中的高效 strtod?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7332558/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com