Swift 3.1:数组太大而无法初始化? (程序只是冻结)

Posted

技术标签:

【中文标题】Swift 3.1:数组太大而无法初始化? (程序只是冻结)【英文标题】:Swift 3.1: Array too large to be initialized? (Program just freezes) 【发布时间】:2017-11-20 03:04:27 【问题描述】:

问题: 我有一个半大的 [Int] 数组,其中包含 ~ 25K 到 60K 元素。它最初由我的第一个程序输出到一个文本文件中,需要作为let 值输入到第二个程序中。为此,我手动将其复制进去。但是,每当我尝试初始化它时,Swift 就会冻结。冻结,我的意思是它不会做任何事情,即使是在一个小时之后。

进一步调查: 我通过创建一个仅包含let test = [the_array] 的一行的测试程序来确认是数组的大小导致了冻结。该程序在一个小时后仍在运行。

我以前使用过包含 400-450K 元素的数组,没有任何问题。但是,这些数组不必初始化为变量/常量,每个元素只包含 1-9 之间的数字。导致冻结的数组肯定有少于 100K 的元素,但每个元素都包含一个介于 100-300K 之间的整数。

如何将数组初始化到第二个程序中,究竟是什么导致了问题?

其他信息:我在 Ubuntu 16.04 64 位上使用 Swift 3.1.1,所以我无法访问 Xcode。如果需要数组的文本文件,请留言。 File is uploaded here

【问题讨论】:

***.com/a/31329368/7347933q 您是否为数组指定了明确的类型:let test: [Int] = [...?如果必须推断类型,Swift 就不能很好地处理大字面量。 @vacawama 哇,我从没想过。我现在就试试。 @vacawama 到目前为止,不幸的是,它仍然获得与以前相同的结果。似乎占用了很多 CPU。 您能发布文件和用于解压该文件的代码吗? 60k Ints 对于现代计算机来说是很小的 【参考方案1】:

我下载了您的文件 - 600KB 的文件对于任何现代计算机来说都是非常小的大小。此代码在我的 2012 iMac 上运行时间不到 1 秒:

let fileURL = URL(fileURLWithPath: "/path/to/file.txt")

let charset = CharacterSet.whitespacesAndNewlines.union(CharacterSet(charactersIn: "[]"))
let fileContent = try! String(contentsOf: fileURL).trimmingCharacters(in: charset)

let array = fileContent.components(separatedBy: ",").flatMap 
    Int($0.trimmingCharacters(in: .whitespaces))


print(array.count) // 74061

【讨论】:

您的代码运行顺畅。 Linux 用户必须删除第一行,而是直接从 String(contentsOfFile: "file_location") 加载 let fileContent,因为在 Linux 的 Foundations 中似乎没有实现 URL。不过似乎有1个问题。当传入 [1, 2, 3, 4, 5, 6, 7, 8] 时,`print(array) 后面的代码给出的值是 [2, 3, 4, 5, 6, 7]。而且计数总是少 2。 出于某种原因,.union(CharacterSet(charactersIn: "[]")) 似乎没有任何效果。如果它适用于mac,那一定是Linux库问题。 let charset = CharacterSet.decimalDigits.inverted 解决了这个问题。 我现在不在电脑附近,但这是一个有趣的观察。您应该向 Apple 报告该错误

以上是关于Swift 3.1:数组太大而无法初始化? (程序只是冻结)的主要内容,如果未能解决你的问题,请参考以下文章

离子资源 ios 给出“图像太大而无法转换”错误

得到“JSON 请求太大而无法反序列化”

字体太大而无法放入缓存

“JSON 请求太大而无法反序列化” MVC KnockoutJs

绘制太大而无法放入 QImage 的图像

矩阵上的 Python PCA 太大而无法放入内存