2024 年 Clojure 状态调查 中分享您的想法!

欢迎!请参阅 关于 页面了解更多关于这个网站如何运作的信息。

0
data.csv

使用 clojure.data.csv 库时遇到的一个问题是,它是基于懒序列构建的,这可能导致处理大量数据时的低效,例如在我机器上,即使没有进行任何转换,解析 1gb 的 CSV 数据也需要大约 50 秒。其他在 JVM 上可用的解析器可以在不到 4 秒内解析这么多的数据。

我想讨论如何将 clojure.data.csv 转移到使用缩减器/变换器模型,以改进性能和资源管理。大体而言,我认为有几个选择

  1. 将此作为 c.d.csv 的次要替代 API 实现,同时保留现有的 API 和实现,以便为遗留用户留出空间。
  2. 完全替换 API,不尝试保留向后兼容性。
  3. 保留相同的公共 API 合同,同时尝试在缩减器/变换器的术语下重新实现。在底层使用变换器,但使用 sequence 保留当前的 parse-csv 懒序列合同,同时为非遗留用户或不需要基于懒序列的实现的用户提供访问新纯变换器/缩减器 API 的途径。

1 和 3 实际上是相同的思想,不过 3 提供了更快的底层实现的好处,可能还有其他选择。

我认为 3 是最佳选择。

选项 1 和 2 引发了是否尝试保持向后兼容性或改善遗留用户体验的问题。

在深入了解缩减器/变换器实现细节之前,我想了解一下核心团队对进一步探索这一领域的看法
这个。

3 答案

0

由 jonase 发布的评论:

你能分享一下这个基准测试吗?在我最初编写库时,我做了一些比较,但没有看到这么大的差异。

我认为在许多情况下,您不需要在内存中保留那些千兆字节的 lbs 懒惰方法是一个重要的功能。

如果我们出于性能考虑添加一些非懒惰解析,我认为这应该是对公共API的补充。

0

评论者:rickmoynihan

我同意不将数据加载到内存中是一个巨大的好处,但我们不应该必然将这个流属性与懒惰/急切混淆。

通过使用reducers/transducers,您仍然可以逐行遍历CSV文件,并消耗固定的内存量。例如,将行数汇总不会消耗内存,即使它是急切的。同样,如果您使用带有可转变为CollReduceCSVFile对象的transducer,并且使用transduce进行转换,您可以通过sequence请求一个懒惰序列的结果,其中解析本身没有支付懒惰税;或者,您也可以请求通过转换为向量来硬加载结果。

对于没有在这个问题上提供任何基准测试结果表示歉意;实际上,是亚历克斯·米勒在我与他短暂的 Slack 对话后建议我写这个问题的——他建议我不必提供时间,因为懒惰的成本众所周知。无论如何,我会整理我用过的计时代码,并将其放到gist或其他地方——可能今天稍后。

0
参考:https://clojure.atlassian.net/browse/DCSV-15 (由rickmoynihan报告)
...