在我的 swift 实现中,一个字符一个字符地读取字符串非常慢
Reading a string char by char is very slow in my swift implementation
我必须在 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 的示例文件,完成任务需要六分多钟。
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
++++ 更新函数 ++++
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 { [=15=] }
stored_idx = 0
stored_cnt = stored.count
}
return stored[0];
}
您对 nextChar
的实施非常低效。
您创建一个 String
,然后一遍又一遍地调用 characters
,然后一遍又一遍地更新那组字符。
为什么不创建 String
然后只存储对其 characters
的引用。然后跟踪一个索引到characters
。与其一遍又一遍地更新它,不如简单地增加索引和 return 下一个字符。无需一遍又一遍地更新字符串。
到达最后一个字符后,阅读文件的下一部分。创建一个新字符串,重新设置字符和索引。
我必须在 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 的示例文件,完成任务需要六分多钟。
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
++++ 更新函数 ++++
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 { [=15=] }
stored_idx = 0
stored_cnt = stored.count
}
return stored[0];
}
您对 nextChar
的实施非常低效。
您创建一个 String
,然后一遍又一遍地调用 characters
,然后一遍又一遍地更新那组字符。
为什么不创建 String
然后只存储对其 characters
的引用。然后跟踪一个索引到characters
。与其一遍又一遍地更新它,不如简单地增加索引和 return 下一个字符。无需一遍又一遍地更新字符串。
到达最后一个字符后,阅读文件的下一部分。创建一个新字符串,重新设置字符和索引。