2024 State of Clojure 问卷调查 中分享您的想法!

欢迎!有关如何工作的更多信息,请参阅关于页面。

0
Clojure

我无法让 nth 在长值索引上起作用

(nth (cycle [:a]) 12321123212397) => 执行错误 (ArithmeticException) 在 java.lang.Math/toIntExact (Math.java:1371)。整数溢出

如果明确尝试强制转换为 Long 也会一样

(nth (cycle [:a]) (long 12321123212397)) => 执行错误 (ArithmeticException) 在 java.lang.Math/toIntExact (Math.java:1371)。整数溢出

任何建议都欢迎。谢谢!

1 个答案

+1

这并不是关于 long 与 int 类型的问题,因为 Clojure 中的整数数字字面量始终为 long 型。这是关于值的范围以及它不适用于 Java 的 int 的原因。

我不知道是否确定,但是我可以推测限制是由于实用性。
Java 中的字符串和数组有一个大小限制,该限制适合 int。通用的 List 接口也可以只用 int 作为索引。

对于索引的 Clojure 集合也是如此。尽管 Clojure 的持久向量从理论上讲可以使用 long 作为基本索引类型,因为它们依赖于大小为 32 的数组,但是这并不实用,因为即使是包含 Integer/MAX_VALUE 个 8 字节数值的普通数组,也会占用 17 GB 的 RAM,而且持久向量不是普通数组。

至于任何懒加载或无随机访问的任何内容,在较高的索引处使用 nth 将是一个非常耗时的不良模式。但这并不意味着它永远不需要,但是需要它的人是一个强烈的信号,表明为手头的问题选择了错误的数据结构。

感谢您的回答。我在数据科学领域工作,我们确实有占用高达数GB RAM的非常大量的数据集。
尽管如此,我理解了您的推理,并将寻找另一种方法。
对于大型数据块,常用的方法是用合适的库代替通用数据结构,例如 https://github.com/scicloj/tablecloth。你在初步讨论中发布的长值不是几个GB,而是100TB :)
我会看看tablecloth。至于这个长值,我只为代码片段虚构了一个;再次感谢!
...