【发布时间】:2018-04-30 10:05:41
【问题描述】:
我正在处理一个 csv 文件,其中最后一列的格式并不总是相同。 每一行都有这样的结构:
"Root/Word1","some string","some string","some œ0'fqw[唃#”≠§
\nfw@\tfa0j
"
"Root/Word2","some string","some string","some string"
...
所以 6 列,最后一个可以包含 \n。这使得很难按组件拆分。 另一个限制是所有字符串都可以是任何可能的特殊字符。这使得使用正则表达式变得困难。
我决定先用蛮力解决问题。 (是的,我已经看到索引偏移量为 O(n)。但无法提出替代方案。)
static func importData(_ db: DB) {
let csvString = readDataFromCSV(fileName: "data", fileType: "csv")!
let totalCharCount = csvString.count
print("total: \(totalCharCount)")
for i in 0..<totalCharCount {
print(i)
if i+5 >= totalCharCount {
continue
}
let index = csvString.index(csvString.startIndex, offsetBy: i)
let endIndex = csvString.index(csvString.startIndex, offsetBy:i+5)
let part = csvString[index ..< endIndex]
if part == "Root/" {
let accum = lookInside(i: i, totalCharCount: totalCharCount, csvString: csvString)
var rows = accum.components(separatedBy: "\",\"")
if var lastt = rows.last {
lastt.removeLast()
lastt.removeLast()
rows[rows.count-1] = lastt
}
}
}
}
static func lookInside(i:Int, totalCharCount: Int, csvString: String) -> String {
var accum = ""
var found = false
var j = i+5
while !found {
if j+5 >= totalCharCount {
found = true
}
let index2 = csvString.index(csvString.startIndex, offsetBy: j)
let endIndex2 = csvString.index(csvString.startIndex, offsetBy:j+5)
if csvString[index2 ..< endIndex2] == "Root/" {
found = true
accum.removeLast()
} else {
accum += String(csvString[index2])
}
j += 1
}
return accum
}
基本上,我正在遍历整个字符串以寻找模式“Root/”。 找到后,我从这一刻前进到模式的下一次出现。
问题是 csv 会生成一个 200k 字符长的字符串,当我在模拟器上运行它时,它会持续很长时间(约 30 分钟)。
所以现在我在这里寻求帮助,因为根据 Instruments,所有时间都消耗在 String.index(offset by) 方法中,该方法被调用了太多次。
【问题讨论】:
-
明显的微优化是只从前一个索引开始索引,而不是每次都从字符串的开头开始。但是,您是否有理由不使用 OTS CSV 解析器?这个临时的似乎在某些情况下会失败。
-
谢谢。好点子。将 thry 你提到的图书馆
-
@Ssswift 所说的不仅仅是微优化。遍历一个字符串是
O(n),由于你每次都是从csvString.startIndex开始,它很快就变成了O(n^2)操作。由于您的问题是关于性能优化,请将完整的 CSV 文件上传到 Pastebin 并在此处包含一个链接 -
你说有 6 列,但我只数 4 列。您能否确认这些列是否可能包含
"?引用双引号(即\")是否合法?还是每条记录准确有 8 个(12 个?)双引号,并且记录的结尾是双引号,这是真的吗?删除Root/是否重要,或者只是您查找记录的方式?
标签: swift string algorithm performance indexing