2016-10-28 3 views
0

Мне нужно прочитать файл char с помощью char в swift. То, как я это делаю, - прочитать фрагмент из FileHandler и вернуть первый символ строки.Чтение строкового символа char очень медленно в моей быстрой реализации

Это мой код до сих пор:

/// 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 

Большое спасибо. пс

++++ UPDATEED ФУНКЦИЯ ++++

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]; 
} 
+0

Используйте инструменты и посмотрите, где все время расходуется. – rmaddy

+0

В трех строках я опубликовал в нижней части сообщения –

ответ

1

Ваша реализация nextChar ужасно неэффективно.

Вы создаете String, а затем снова и снова вызываете characters, и вы снова и снова обновляете этот набор символов.

Почему бы не создать String, а затем сохранить только ссылку на его characters. А затем отслеживать индекс в characters. Вместо того, чтобы обновлять его снова и снова, просто увеличивайте индекс и возвращайте следующий символ. Нет необходимости обновлять строку снова и снова.

Как только вы дойдете до последнего символа, прочитайте следующий фрагмент файла. Создайте новую строку, сбросьте символы и индекс.

+0

Спасибо большое! –

+0

У меня теперь хранится '' 'var: [Character] = Array()' '' и возвращает '' 'let r = stored [stored_idx]; stored_idx + = 1; return r} '' '1.4 быстрый, но файл 150mb занимает еще 2,33 минуты. Есть ли даже более эффективная реализация? –

+0

вот мой текущий класс: https://gist.github.com/petershaw/51db7df73e4bf06bb935a3abb41d8b64 –