在我的快速实现中,一个字符一个字符地读取字符串非常慢



我必须在swift中逐个字符地读取文件。我这样做的方式是从FileHandler读取一个块,并返回字符串的第一个字符。

这是我到目前为止的代码:

/// Return next character, or nil on EOF.
func nextChar() -> Character? {
    precondition(fileHandle != nil, "Attempt to read from closed file")
    if atEof {
        return nil
    }
    if self.stored.characters.count > 0 {
        let c: Character = self.stored.characters.first!
        stored.remove(at: self.stored.startIndex)
        return c
    }
    let tmpData = fileHandle.readData(ofLength: (4096))
    print("n---- file read ---n" , terminator: "")
    if tmpData.count == 0 {
        return nil
    }
    self.stored = NSString(data: tmpData, encoding: encoding.rawValue) as String!
    let c: Character = self.stored.characters.first!
    self.stored.remove(at: stored.startIndex)
    return c
}

我的问题是字符的返回非常慢。这是我的测试实现:

if let aStreamReader = StreamReader(path: file) {
    defer {
        aStreamReader.close()
    }
    while let char = aStreamReader.nextChar() {
        print("(char)", terminator: "")
        continue
    }
}

即使没有打印,也要花很长时间才能把文件读到最后。

对于1.4mb的样例文件,完成任务需要6分钟以上。

time ./.build/debug/read a.txt
real    6m22.218s
user    6m13.181s
sys     0m2.998s
你对如何加快这部分的速度有什么意见吗?
let c: Character = self.stored.characters.first!
stored.remove(at: self.stored.startIndex)
return c

非常感谢。ps

++++ UPDATEED FUNCTION ++++

func nextChar() -> Character? {
    //precondition(fileHandle != nil, "Attempt to read from closed file")
    if atEof {
        return nil
    }
    if stored_cnt > (stored_idx + 1) {
        stored_idx += 1
        return stored[stored_idx]
    }
    let tmpData = fileHandle.readData(ofLength: (chunkSize))
    if tmpData.count == 0 {
        atEof = true
        return nil
    }
    if let s = NSString(data: tmpData, encoding: encoding.rawValue) as String! {
        stored = s.characters.map { $0 }
        stored_idx = 0
        stored_cnt = stored.count
    }
    return stored[0];
}

您对nextChar的实现效率非常低。

你创建一个String,然后一次又一次调用characters,你一次又一次地更新那组字符。

为什么不创建String,然后只存储对其characters的引用?然后跟踪索引到characters。而不是一次又一次地更新它,只需增加索引并返回下一个字符。无需一次又一次地更新字符串

读取到最后一个字符后,读取文件的下一部分。创建一个新的字符串,重置字符和索引

最新更新