- Rust and CSV parsing 译文(用 Rust 实现 csv 解析-part1)
- 原文链接:https://blog.burntsushi.net/csv/
- 原文作者:BurntSushi
- 译文来自:https://github.com/suhanyujie/article-transfer-rs/
- 译者:suhanyujie
- 译者博客:suhanyujie
- ps:水平有限,翻译不当之处,还请指正。
- 标签:Rust,csv
随着 csv 1.0 刚刚发布,关于使用 Rust 读取和写入 csv 数据的教程是时候发布了。本教程针对的是刚入门的 Rust 程序员,因此有相当多的示例,并花了一些时间在基础的概念解释上。你可能会发现,其中部分内容很有用,但对有经验的 Rust 程序员来说,快速浏览会更有利。
有关 Rust 的介绍,请参考官方权威指南。如果你还没有写过一行 Rust 代码,但有其他编程语言的经验,那么你可能不需要看权威指南就能读懂本教程。
最后,这个博客的文章会作为一个教程被包含在 API 文档中,并且后续会有所更新。
目标读者:Rust 初学者。
目录
- csv 1.0 release
- Setup
- 错误处理基础
- 切换到可恢复的错误处理
- 读取 CSV
- 读取 header
- 分隔符、引号和可变长度的数据记录
- 使用 Serde 读取
- 使用 Serde 处理不合法的数据
- 写入 CSV
- 写入制表符分隔的数据值
- 使用 Serde 写入
- 管道操作
- 通过搜索筛选
- 通过人口统计筛选
- 性能
- Amortizing 分配
- Serde 和零分配
- 不使用标准库进行解析
- Closing thoughts
CSV 1.0 发布
在开始学习本教程之前,我想简要介绍 1.0 的方向。rust-csv 仓库的第一次提交是 2014.3.22,这比 Rust 1.0 发行版要早了一年多。对于那些从 1.0 之前就开始接触 Rust 的人来说,肯定还记得该语言发生了多大的变化。当然,我也改变了,因为我变得更熟练和习惯于它。然而,从最初的版本开始,csv 库的 API 基本保持不变。这使得提高性能和修复 bug 变得更加困难,最糟糕的是,使用了旧版的序列化架构。
CSV1.0 版本标志着这是一个更快的库,拥有更好的 API,并支持 Rust 序列化框架 Serde。
新的 CSV 库附带一个 csv-core
crate,它可以在没有 Rust 标准库的情况下解析 CSV 数据,并且主要负责性能改进。特别地,旧版的 CSV 库使用了一种有限状态机,它有很大的开销。而 csv-core crate 将其解析为一个基于 DFA 的表,该表在堆栈上只占用几百个字节。结果,我们得到超过 2 倍的性能改进:
count_game_deserialize_owned_bytes 30,404,805 (85 MB/s) 23,878,089 (108 MB/s) -6,526,716 -21.47% x 1.27
count_game_deserialize_owned_str 30,431,169 (85 MB/s) 22,861,276 (113 MB/s) -7,569,893 -24.88% x 1.33
count_game_iter_bytes 21,751,711 (119 MB/s) 11,873,257 (218 MB/s) -9,878,454 -45.41% x 1.83
count_game_iter_str 25,609,184 (101 MB/s) 13,769,390 (188 MB/s) -11,839,794 -46.23% x 1.86
count_game_read_bytes 12,110,082 (214 MB/s) 6,686,121 (388 MB/s) -5,423,961 -44.79% x 1.81
count_game_read_str 15,497,249 (167 MB/s) 8,269,207 (314 MB/s) -7,228,042 -46.64% x 1.87
count_mbta_deserialize_owned_bytes 5,779,138 (125 MB/s) 3,775,874 (191 MB/s) -2,003,264 -34.66% x 1.53
count_mbta_deserialize_owned_str 5,777,055 (125 MB/s) 4,353,921 (166 MB/s) -1,423,134 -24.63% x 1.33
count_mbta_iter_bytes 3,991,047 (181 MB/s) 1,805,387 (400 MB/s) -2,185,660 -54.76% x 2.21
count_mbta_iter_str 4,726,647 (153 MB/s) 2,354,842 (307 MB/s) -2,371,805 -50.18% x 2.01
count_mbta_read_bytes 2,690,641 (268 MB/s) 1,253,111 (577 MB/s) -1,437,530 -53.43% x 2.15
count_mbta_read_str 3,399,631 (212 MB/s) 1,743,035 (415 MB/s) -1,656,596 -48.73% x 1.95
count_nfl_deserialize_owned_bytes 10,608,513 (128 MB/s) 5,828,747 (234 MB/s) -4,779,766 -45.06% x 1.82
count_nfl_deserialize_owned_str 10,612,366 (128 MB/s) 6,814,770 (200 MB/s) -3,797,596 -35.78% x 1.56
count_nfl_iter_bytes 6,798,767 (200 MB/s) 2,564,448 (532 MB/s) -4,234,319 -62.28% x 2.65
count_nfl_iter_str 7,888,662 (172 MB/s) 3,579,865 (381 MB/s) -4,308,797 -54.62% x 2.20
count_nfl_read_bytes 4,588,369 (297 MB/s) 1,911,120 (714 MB/s) -2,677,249 -58.35% x 2.40
count_nfl_read_str 5,755,926 (237 MB/s) 2,847,833 (479 MB/s) -2,908,093 -50.52% x 2.02
count_pop_deserialize_owned_bytes 11,052,436 (86 MB/s) 8,848,364 (108 MB/s) -2,204,072 -19.94% x 1.25
count_pop_deserialize_owned_str 11,054,638 (86 MB/s) 9,184,678 (104 MB/s) -1,869,960 -16.92% x 1.20
count_pop_iter_bytes 6,190,345 (154 MB/s) 3,110,704 (307 MB/s) -3,079,641 -49.75% x 1.99
count_pop_iter_str 7,679,804 (124 MB/s) 4,274,842 (223 MB/s) -3,404,962 -44.34% x 1.80
count_pop_read_bytes 3,898,119 (245 MB/s) 2,218,535 (430 MB/s) -1,679,584 -43.09% x 1.76
count_pop_read_str 5,195,237 (183 MB/s) 3,209,998 (297 MB/s) -1,985,239 -38.21% x 1.62
以上就是所有的介绍了,我们可以开始了!