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

欢迎!请参阅关于页面了解更多关于这个站点如何工作的情况。

0
data.csv

在使用clojure.data.csv库时,一个问题是在处理大量数据时,它基于惰性序列,这会导致效率低下,例如,在我机器上的CSV的基线解析只要50秒就能完成1gb数据,而其他JVM上可用的解析器可以在不到4秒内解析这么大量的数据。

我想讨论如何将clojure.data.csv移植到使用Reducer/Transducer模型,以改进性能和资源处理。概括来说,我认为有几个选项

  1. 将其作为c.d.csv的二级替代API实现,保留现有API和实现,以方便遗留用户。
  2. 完全替换API,不尝试保留向后兼容性。
  3. 保留相同的公开API接口,同时尝试在底部使用Reducer/Transducer重新实现。使用transducer,但使用sequence保留当前parse-csv惰性序列的合同,同时为新用户或不需要基于惰性序列实现的用户提供新的纯transducer/reducer API。

选项1和3基本上是相同的概念,只是选项3的用户能够受益于更快的底层实现,也可能有其他选项。

我认为如果可能的话,选项3是最好的选择。

选项1和2引起了一个问题,即不尝试向后兼容或改善遗留用户的体验。

在深入了解Reducer/Transducer实现细节之前,我想了解一下核心团队对这个进一步探索的看法

3 答案

0

评论者:jonase

你能分享这个基准测试吗?我在编写库时做过一些比较,我没有看到如此大的差异。

我认为惰性方法在很多情况下都是重要的特性,在这些情况下你不想加载所有这些千兆字节的数据到内存中。

如果我们为了性能原因添加一些非懒解析,我认为它应该是公开API的补充。

0

评论者:rickmoynihan

我同意不将数据加载到内存中是一个巨大的优势,但我们不能把这种流属性与懒惰/急切属性混为一谈。

通过使用reducers/transducers,你可以逐行流式传输CSV文件并消耗恒定的内存量,例如,将行数归一化不会消耗内存,即使它很急切。同样,如果我们通过使用transduce将可CollReduceCSVFile对象转换,你可以通过sequence请求一个懒惰序列的结果,其中解析本身没有付出懒惰的代价;或者你也可以通过将其转换为一个向量来请求将结果加载到内存中。

很抱歉没有在此票证中提供任何基准测试结果;实际上是Alex Miller建议我在这件事上写这个票证,我们在Slack上简单地讨论过这个问题——他建议我无需提供计时,因为懒惰的成本是众所周知的。无论如何,我会整理我用来获取计时的代码,并将其放入gist或其他的东西——也许在今天晚些时候。

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