Duck 三种方式:C#、C++、C 之间的文件 I/O 和字符串性能比较

基准

我想出的问题是程序将输入 CSV 文件加载到数据结构数组中,并使用数据结构将数据写回输出 CSV 文件。您的基本输入/输出数据处理问题,无需任何数据处理。这是一个文件 I/O 和数据结构序列化基准测试。

我选择对 CSV 数据使用 Unicode 编码的文本文件,因为 C# 是一种 Unicode 语言,而 C/C++ 在这一点上可以很好地处理 Unicode 数据。我选择每行 CSV 文本有七个数据字段,典型的人口统计资料:名字、姓氏、地址行 1、地址行 2、城市、州和邮政编码。为简单起见,每个字段限制为 127 个字符的 Unicode 文本。

CSV 生成程序(gen附件代码中的“”项目)将 100,000 行此随机 CSV 数据输出到桌面上的文件中。

C#
收缩▲   

让我们跳到重点:结果是什么?

以下是不同程序的加载和编写阶段的时间安排。程序通过加载/写入周期运行四次。我从每个程序的所有运行中获取了最好的加载和写入时间,最好的。

方法/语言负载(毫秒)写入(毫秒)
方法 1:带循环的 C#(网络)317178
方法 2:批量 C# (net2)223353
方法 3:C++ 循环(类)2,4891,379
方法 4:C 批次(结构)107147
方法 5:C++ 批处理(类 2)202136
方法 6:C/C++ 批处理(recordio)108149

结论和兴趣点

C# 程序、循环和批处理,干净且易于阅读并且具有良好的性能。循环使用StreamReader/StreamWriter并且直观且易于开发和维护。批处理程序使用File类函数ReadAllLines/WriteAllLines并且在读取、LINQ 等方面比 C# 循环程序快得多,而在写入方面则更慢。鉴于此,您将使用ReadAllLines/ LINQ 进行加载和StreamWriter写入。

大新闻是方法 3:C++ 循环(类)有一些非常错误的地方。它归结std::getline为加载调用和写入流输出;其他代码花费很少。我对重现这些数字并报告如何解决这些性能问题的人感兴趣。

C 批处理程序在加载数据方面轻松胜过其他程序,因为它使用固定大小的字符串打包在一起,struct按顺序存储在一个数组中,因此数据局部性非常好。我们在大约 100 毫秒内读取了 90 MB 的 CSV。哇!由于某种原因,C 程序将数据写入输出文件的速度较慢;代码看起来很干净,不确定。

受 C 程序的启发,“C++ 批处理”程序在读取数据方面并不接近 C,但在写出数据方面却优于 C。你会选择 C ​​来阅读和 C++ 来写作。

方法 6,recordio - 与 rodeo 押韵 - C 和 C++ 批处理方法的混合,在一个可重用的包中,产生 108 / 149,优于 C# 的最佳值 223 / 178。写入性能的差异并不显着。负载性能的 2 倍加速不容忽视。使用固定长度的字符串打包到一个 s 向量中,这是任何 C++ s 或 C# 字符串的struct存储都无法比拟的。wstring代码很干净,在实现和使用可重用类的测试驱动程序说明中,都有。

我的总体建议是在 C/C++ 中使用具有固定宽度字段的结构,您可能会如何想象事物存储在数据库中,并利用 recordio 或类似工具来获得出色的文件和字符串 I/ O。

如果您使用 C# 代码,请使用File.ReadAllLines和 LINQ 加载数据并将StreamWriter其写回,并获得可观的性能以及出色的生产力和安全性。

以下是有关不同方法的更多信息。

方法 1:带有循环的 C#

在附加的代码中,这是“ net”项目。这可能是最直观的语言和方法。您已经StreamReader收集了数据,并将StreamWriter其全部写出来:

C#
收缩▲    方法 2:批量使用 C#

在附件源中,这是“ net2”项目。您可能会对自己说,“循环很乏味。我可以使用File类函数ReadAllLines来做大量的事情。我相信在 .NET 中!” 这肯定是更少的代码......

C#
方法 3:C++ 循环

C++ 在 Unicode 文件 I/O 和流方面取得了长足的进步。现在可以轻松编写与 C# 的 Loopy 方法 1 相媲美的 C++ 代码,以提高可读性和简单性:

C++
收缩▲   

对于文件加载步骤,快速计时检查显示所有时间都花在了std::getline()调用上。而对于文件写入步骤,所有的时间都花在了输出循环上,还有什么地方呢?这个谜题留给读者作为练习。这个简单的代码有什么问题?

方法 4:C 批次

如果我们愿意将整个文本加载到内存中,那么我们可以在适当的位置对数据进行切片和切块,并利用固定长度的字符串缓冲区和利用数据局部性和不安全操作的字符级字符串操作. 多么有趣!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值