作者在搜索引擎工作时经常遇到从磁盘读取数据的问题,为此进行了一系列性能测试。
- 测试内容及工具:测试读取 10 亿条温度测量数据(每条数据对应一个城市)并进行聚合(求最小值、最大值、平均值)的性能,涵盖 Parquet、Protobuf、JDBC、Java 的 stream 和 NIO APIs 等,还将 DuckDB 作为参考基准。
不同读取方式的性能对比:
- DataInputStream + BufferedInputStream(DIS+BIS):使用 InputStream 读取数据,运行时间约 300s,磁盘占用 10GB。
- Streaming the data over JDBC:通过 JDBC 读取数据,运行时间 620s,磁盘占用 3GB。
- Protobuf + BIS:使用 Protobuf 读取数据,运行时间 580s,磁盘占用 7.5GB;使用 Java NIO 读取 Protobuf 数据(Protobuf + NIO),运行时间 91s,磁盘占用 12.3GB。
- Parquet in Java with parquet-floor shim:使用 parquet-floor shim 读取 Parquet 文件,运行时间 134s,磁盘占用 2.4GB。
- ObjectInputStream(OIS):使用 ObjectInputStream 读取数据,运行时间 260s,磁盘占用 14GB。
- Custom solutions(自定义方案):通过自定义方式读取数据,包括简单序列化、去除字符串解析、内存映射等操作,运行时间逐渐缩短,其中 Custom Encoding 2 + mmap 运行时间 5.1s,磁盘占用 2.8GB。
- 结果分析:作者对测试结果感到困惑,一些被认为性能较好的解决方案实际运行速度比预期慢一个数量级,磁盘 I/O 虽为瓶颈,但不应使速度降低这么多,作者还提供了包含这些基准测试的仓库https://github.com/vlofgren/Serialization1BRCBenchmark/。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。