【发布时间】:2020-12-12 01:26:30
【问题描述】:
我的代码按预期工作,我只是想加快速度。
我有一个包含数百万传感器测量值的数据库表。 当我在数据库中查询过去 2 个月的测量值(按传感器名称排序)时,我得到了大约 300,000 个结果。
然后我继续逐步检查结果并希望从数据中创建嵌套结构对象。 这里有一些较短的伪代码:
struct Measurement {
var date: Int
var temp: Double?
...
}
struct Sensor {
var sensorName: String
var measurements: [Measurement]
}
var sensors:[Sensor] = []
...
for r in dbResults {
...
let m = Measurement(date: r.date, temp: r.temp1, ... )
if let index = sensors.firstIndex(where: { $0.sensorName = r.name }) {
sensors[index].measurements.append(m)
} else {
sensors.append(Sensor(sensorName: r.name, measurements: [m]))
}
}
然而,这相当慢。循环完成大约需要一分钟。
有没有办法加快这个过程?我假设.firstIndex 需要太长时间。
我正在考虑在并行线程上创建对象,但我不确定如何最好地做到这一点,而不会在检查 .firstIndex 时冒竞争条件的风险。
感谢您的任何想法
【问题讨论】:
-
数据中有多少个传感器?如果 300,000 次测量分布在 10 个传感器上,我怀疑
firstIndex花费的时间太长。您是否使用 Instruments 来检查什么耗时过长? -
绝对同意以上观点。当然,如果有数千个传感器,那么
.firstIndex(where:)是低效的。您可以利用它们已排序的事实,只查看最后一个索引,而不是搜索第一个匹配项。提前为阵列保留空间,而不是逐步增长它们也可能是有意义的。很大程度上取决于数据的分布 -
传感器的数量各不相同,但大多数时候有 4,000-6,000 个。将尝试
last的想法。如何在swift中保留空间?