1BRC数值计算:定点数与浮点数性能对比
【免费下载链接】1brc 一个有趣的探索,看看用Java如何快速聚合来自文本文件的10亿行数据。 项目地址: https://gitcode.com/GitHub_Trending/1b/1brc
在处理大规模数据聚合任务时,数值计算方式的选择对性能有着决定性影响。One Billion Row Challenge(1BRC)项目为我们提供了一个绝佳的研究案例,展示了定点数(Fixed-Point)与浮点数(Floating-Point)在十亿级数据计算中的性能差异。
数值表示基础:定点数 vs 浮点数
浮点数表示
// 传统浮点数实现
private static class MeasurementAggregator {
private double min = Double.POSITIVE_INFINITY;
private double max = Double.NEGATIVE_INFINITY;
private double sum;
private long count;
}
定点数表示
// 定点数优化实现
private static final class Result {
short min, max; // 定点数表示,实际值 = 存储值 / 10.0
int count;
long sum; // 定点数累加和
}
性能对比分析
内存占用对比
| 数据类型 | 存储大小 | 计算复杂度 | 精度控制 |
|---|---|---|---|
| double | 8字节 | 高 | 自动 |
| short | 2字节 | 低 | 手动 |
| int | 4字节 | 中 | 手动 |
| long | 8字节 | 中 | 手动 |
计算效率对比
定点数实现关键技术
1. 数值解析优化
// 传统浮点解析 - 性能瓶颈
double value = Double.parseDouble(parts[1]);
// 定点数解析 - 高性能
private static long convertIntoNumber(int decimalSepPos, long numberWord) {
int shift = 28 - decimalSepPos;
long signed = (~numberWord << 59) >> 63;
long designMask = ~(signed & 0xFF);
long digits = ((numberWord & designMask) << shift) & 0x0F000F0F00L;
long absValue = ((digits * 0x640a0001) >>> 32) & 0x3FF;
return (absValue ^ signed) - signed;
}
2. 累加与统计优化
// 定点数统计操作
private static void record(Result existingResult, long number) {
if (number < existingResult.min) {
existingResult.min = (short) number;
}
if (number > existingResult.max) {
existingResult.max = (short) number;
}
existingResult.sum += number;
existingResult.count++;
}
精度处理策略
精度转换表
| 操作类型 | 浮点数实现 | 定点数实现 | 精度影响 |
|---|---|---|---|
| 存储 | 直接存储 | 值 × 10 | 保留1位小数 |
| 累加 | 直接累加 | 整数累加 | 无精度损失 |
| 平均值 | sum/count | (sum/10.0)/count | 最终转换 |
舍入处理对比
// 浮点数舍入
private double round(double value) {
return Math.round(value * 10.0) / 10.0;
}
// 定点数结果输出
public String toString() {
return round(((double) min) / 10.0) + "/" +
round((((double) sum) / 10.0) / count) + "/" +
round(((double) max) / 10.0);
}
性能实测数据
根据1BRC官方测试结果:
| 排名 | 实现方式 | 耗时(秒) | 数值处理技术 |
|---|---|---|---|
| 1 | ThomasWue | 1.535 | 定点数+Unsafe |
| 2 | ArtsiomKorzun | 1.587 | 定点数优化 |
| 16 | MeryKitty | 3.210 | 浮点数标准 |
| 基准 | Baseline | >120 | 纯浮点数 |
性能提升幅度:最高达到78倍
技术实现要点
内存布局优化
CPU缓存友好性
定点数实现具有更好的缓存局部性:
- 更小的数据结构尺寸
- 连续的内存访问模式
- 减少缓存行污染
适用场景分析
推荐使用定点数的场景
- 固定精度需求:如温度数据(1位小数)
- 大规模数据聚合:十亿级以上记录
- 性能敏感应用:实时数据处理
- 内存受限环境:嵌入式系统或移动设备
推荐使用浮点数的场景
- 动态精度需求:科学计算
- 小规模数据处理:千级以下记录
- 开发便捷性优先:原型开发阶段
- 复杂数学运算:三角函数、指数运算
最佳实践建议
定点数实现 checklist
- 确定合适的缩放因子(如×10、×100)
- 实现高效的字符串到整数解析
- 设计紧凑的数据结构布局
- 处理整数溢出边界情况
- 实现正确的精度还原逻辑
性能优化策略
// 批量处理优化示例
while (scanner.hasNext()) {
long word = scanner.getLong();
long delimiterMask = findDelimiter(word);
long wordB = scanner.getLongAt(scanner.pos() + 8);
long delimiterMaskB = findDelimiter(wordB);
Result result = findResult(word, delimiterMask, wordB, delimiterMaskB, scanner);
long number = scanNumber(scanner);
record(result, number);
}
总结
1BRC项目的实践表明,在大规模数据聚合场景中,定点数相比浮点数能够带来显著的性能提升。关键优势包括:
- 内存效率:减少50-75%的内存占用
- 计算速度:提升3-4倍的解析和计算性能
- 缓存友好:更好的CPU缓存利用率
- 精度可控:避免浮点数精度误差累积
然而,这种优化需要开发者对数据特性和业务需求有深入理解,在精度和性能之间做出合理权衡。对于固定精度的数值计算任务,定点数无疑是更优的选择。
【免费下载链接】1brc 一个有趣的探索,看看用Java如何快速聚合来自文本文件的10亿行数据。 项目地址: https://gitcode.com/GitHub_Trending/1b/1brc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



